summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/AsyncFileSystem.cpp5
-rw-r--r--Source/WebCore/platform/AsyncFileSystem.h3
-rw-r--r--Source/WebCore/platform/DateComponents.cpp40
-rw-r--r--Source/WebCore/platform/DateComponents.h9
-rw-r--r--Source/WebCore/platform/DateTimeChooser.h2
-rw-r--r--Source/WebCore/platform/DragImage.h4
-rw-r--r--Source/WebCore/platform/FractionalLayoutUnit.h40
-rw-r--r--Source/WebCore/platform/KURL.cpp1
-rw-r--r--Source/WebCore/platform/KURLGoogle.cpp1
-rw-r--r--Source/WebCore/platform/KURLWTFURL.cpp12
-rw-r--r--Source/WebCore/platform/KURLWTFURLImpl.h3
-rw-r--r--Source/WebCore/platform/Language.cpp2
-rw-r--r--Source/WebCore/platform/LocalizedStrings.h27
-rwxr-xr-xSource/WebCore/platform/MIMETypeRegistry.cpp13
-rw-r--r--Source/WebCore/platform/MIMETypeRegistry.h5
-rw-r--r--Source/WebCore/platform/MemoryPressureHandler.h1
-rw-r--r--Source/WebCore/platform/PlatformMemoryInstrumentation.h1
-rw-r--r--Source/WebCore/platform/ScrollAnimatorNone.cpp42
-rw-r--r--Source/WebCore/platform/ScrollAnimatorNone.h2
-rw-r--r--Source/WebCore/platform/ScrollView.h2
-rw-r--r--Source/WebCore/platform/ScrollableArea.h4
-rw-r--r--Source/WebCore/platform/SharedBuffer.cpp2
-rw-r--r--Source/WebCore/platform/ThreadTimers.cpp1
-rw-r--r--Source/WebCore/platform/Timer.cpp18
-rw-r--r--Source/WebCore/platform/Timer.h6
-rw-r--r--Source/WebCore/platform/TouchFlingPlatformGestureCurve.cpp4
-rw-r--r--Source/WebCore/platform/audio/AudioBus.cpp10
-rw-r--r--Source/WebCore/platform/audio/AudioBus.h4
-rw-r--r--Source/WebCore/platform/audio/AudioChannel.cpp19
-rw-r--r--Source/WebCore/platform/audio/AudioChannel.h4
-rw-r--r--Source/WebCore/platform/audio/EqualPowerPanner.cpp5
-rw-r--r--Source/WebCore/platform/audio/HRTFElevation.cpp2
-rw-r--r--Source/WebCore/platform/audio/VectorMath.cpp155
-rw-r--r--Source/WebCore/platform/audio/VectorMath.h3
-rw-r--r--Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp2
-rw-r--r--Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp37
-rw-r--r--Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp9
-rw-r--r--Source/WebCore/platform/blackberry/AsyncFileSystemBlackBerry.cpp3
-rw-r--r--Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp243
-rw-r--r--Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h26
-rw-r--r--Source/WebCore/platform/blackberry/ClipboardBlackBerry.cpp6
-rw-r--r--Source/WebCore/platform/blackberry/ClipboardBlackBerry.h2
-rw-r--r--Source/WebCore/platform/blackberry/CookieManager.cpp4
-rw-r--r--Source/WebCore/platform/blackberry/CookieMap.cpp4
-rw-r--r--Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp1
-rw-r--r--Source/WebCore/platform/blackberry/MIMETypeRegistryBlackBerry.cpp5
-rw-r--r--Source/WebCore/platform/blackberry/PageClientBlackBerry.h2
-rw-r--r--Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp18
-rw-r--r--Source/WebCore/platform/blackberry/PlatformKeyboardEventBlackBerry.cpp2
-rw-r--r--Source/WebCore/platform/blackberry/ReadOnlyLatin1String.h50
-rw-r--r--Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp7
-rw-r--r--Source/WebCore/platform/cf/BinaryPropertyList.cpp2
-rw-r--r--Source/WebCore/platform/cf/RunLoopTimerCF.cpp6
-rw-r--r--Source/WebCore/platform/chromium/ChromiumDataObject.cpp8
-rw-r--r--Source/WebCore/platform/chromium/ChromiumDataObject.h4
-rw-r--r--Source/WebCore/platform/chromium/ClipboardChromium.cpp7
-rw-r--r--Source/WebCore/platform/chromium/ClipboardChromium.h2
-rw-r--r--Source/WebCore/platform/chromium/LanguageChromium.cpp4
-rw-r--r--Source/WebCore/platform/chromium/PlatformSupport.h130
-rw-r--r--Source/WebCore/platform/chromium/PopupListBox.cpp10
-rw-r--r--Source/WebCore/platform/chromium/PopupMenuChromium.cpp3
-rw-r--r--Source/WebCore/platform/chromium/PopupMenuChromium.h3
-rw-r--r--Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp1
-rw-r--r--Source/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp65
-rw-r--r--Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm31
-rw-r--r--Source/WebCore/platform/chromium/support/WebAudioBus.cpp13
-rw-r--r--Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp2
-rw-r--r--Source/WebCore/platform/chromium/support/WebMediaConstraints.cpp36
-rw-r--r--Source/WebCore/platform/chromium/support/WebRTCDataChannel.cpp142
-rw-r--r--Source/WebCore/platform/chromium/support/WebRTCStatsRequest.cpp (renamed from Source/WebCore/platform/text/mac/LocalizedNumberMac.mm)63
-rw-r--r--Source/WebCore/platform/chromium/support/WebRTCStatsResponse.cpp76
-rw-r--r--Source/WebCore/platform/chromium/support/WebURLRequest.cpp2
-rw-r--r--Source/WebCore/platform/chromium/support/WebURLResponse.cpp4
-rw-r--r--Source/WebCore/platform/efl/AsyncFileSystemEfl.cpp128
-rw-r--r--Source/WebCore/platform/efl/AsyncFileSystemEfl.h61
-rw-r--r--Source/WebCore/platform/efl/ClipboardEfl.cpp4
-rw-r--r--Source/WebCore/platform/efl/ClipboardEfl.h2
-rw-r--r--Source/WebCore/platform/efl/RenderThemeEfl.cpp36
-rw-r--r--Source/WebCore/platform/efl/RenderThemeEfl.h2
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp110
-rw-r--r--Source/WebCore/platform/graphics/ANGLEWebKitBridge.h13
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.cpp13
-rw-r--r--Source/WebCore/platform/graphics/BitmapImage.h2
-rw-r--r--Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp14
-rw-r--r--Source/WebCore/platform/graphics/DisplayRefreshMonitor.h2
-rw-r--r--Source/WebCore/platform/graphics/Extensions3D.h16
-rw-r--r--Source/WebCore/platform/graphics/FloatSize.h2
-rw-r--r--Source/WebCore/platform/graphics/Font.cpp48
-rw-r--r--Source/WebCore/platform/graphics/Font.h49
-rw-r--r--Source/WebCore/platform/graphics/FontCache.cpp79
-rw-r--r--Source/WebCore/platform/graphics/FontCache.h18
-rw-r--r--Source/WebCore/platform/graphics/FontData.h4
-rw-r--r--Source/WebCore/platform/graphics/FontFallbackList.cpp18
-rw-r--r--Source/WebCore/platform/graphics/FontFallbackList.h12
-rw-r--r--Source/WebCore/platform/graphics/FontFastPath.cpp125
-rw-r--r--Source/WebCore/platform/graphics/FontMetrics.h12
-rw-r--r--Source/WebCore/platform/graphics/FontSelector.h3
-rw-r--r--Source/WebCore/platform/graphics/FontWidthVariant.h12
-rw-r--r--Source/WebCore/platform/graphics/GlyphBuffer.h87
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp122
-rw-r--r--Source/WebCore/platform/graphics/GlyphPageTreeNode.h39
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext.h2
-rw-r--r--Source/WebCore/platform/graphics/GraphicsContext3D.h54
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayer.cpp55
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayer.h24
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayerClient.h5
-rw-r--r--Source/WebCore/platform/graphics/GraphicsLayerFactory.h49
-rw-r--r--Source/WebCore/platform/graphics/Image.h6
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.cpp8
-rw-r--r--Source/WebCore/platform/graphics/ImageBuffer.h2
-rw-r--r--Source/WebCore/platform/graphics/IntPoint.h21
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.cpp7
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayer.h12
-rw-r--r--Source/WebCore/platform/graphics/MediaPlayerPrivate.h6
-rw-r--r--Source/WebCore/platform/graphics/NativeImagePtr.h9
-rw-r--r--Source/WebCore/platform/graphics/OpenGLESShims.h2
-rw-r--r--Source/WebCore/platform/graphics/Path.cpp2
-rw-r--r--Source/WebCore/platform/graphics/SegmentedFontData.cpp5
-rw-r--r--Source/WebCore/platform/graphics/SegmentedFontData.h10
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.cpp22
-rw-r--r--Source/WebCore/platform/graphics/SimpleFontData.h65
-rw-r--r--Source/WebCore/platform/graphics/TextRun.h26
-rw-r--r--Source/WebCore/platform/graphics/TiledBacking.h23
-rw-r--r--Source/WebCore/platform/graphics/TiledBackingStore.cpp17
-rw-r--r--Source/WebCore/platform/graphics/TiledBackingStore.h3
-rw-r--r--Source/WebCore/platform/graphics/WOFFFileFormat.cpp25
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.cpp83
-rw-r--r--Source/WebCore/platform/graphics/WidthIterator.h21
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp2
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp4
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h30
-rw-r--r--Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm237
-rw-r--r--Source/WebCore/platform/graphics/blackberry/DisplayRefreshMonitorBlackBerry.cpp2
-rw-r--r--Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp27
-rw-r--r--Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp9
-rw-r--r--Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.h4
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp4
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp22
-rw-r--r--Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp4
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp48
-rw-r--r--Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h15
-rw-r--r--Source/WebCore/platform/graphics/blackberry/TextureCacheCompositingThread.cpp6
-rw-r--r--Source/WebCore/platform/graphics/blackberry/VideoLayerWebKitThread.cpp4
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp252
-rw-r--r--Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h14
-rw-r--r--Source/WebCore/platform/graphics/ca/PlatformCALayer.h3
-rw-r--r--Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h2
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm8
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/TileCache.h12
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/TileCache.mm61
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm13
-rw-r--r--Source/WebCore/platform/graphics/ca/mac/WebTileLayer.mm2
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp8
-rw-r--r--Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp6
-rw-r--r--Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp11
-rw-r--r--Source/WebCore/platform/graphics/cairo/FontCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/GLContext.cpp97
-rw-r--r--Source/WebCore/platform/graphics/cairo/GLContext.h14
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp51
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp10
-rw-r--r--Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp2
-rw-r--r--Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp44
-rw-r--r--Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp22
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.cpp32
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.h5
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.cpp27
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm11
-rw-r--r--Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h9
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp24
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp38
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp13
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp12
-rw-r--r--Source/WebCore/platform/graphics/chromium/VDMXParser.cpp3
-rw-r--r--Source/WebCore/platform/graphics/clutter/GraphicsContext3DClutter.cpp5
-rw-r--r--Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp9
-rw-r--r--Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.cpp109
-rw-r--r--Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h (renamed from Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h)31
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp909
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp1100
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h204
-rw-r--r--Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.cpp57
-rw-r--r--Source/WebCore/platform/graphics/egl/GLContextEGL.cpp276
-rw-r--r--Source/WebCore/platform/graphics/egl/GLContextEGL.h68
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterConstants.h50
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp6
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h10
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp9
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgram.h4
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp18
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h14
-rw-r--r--Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp21
-rw-r--r--Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp23
-rw-r--r--Source/WebCore/platform/graphics/filters/FECustomFilter.cpp18
-rw-r--r--Source/WebCore/platform/graphics/filters/FECustomFilter.h2
-rw-r--r--Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp47
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.cpp13
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMorphology.cpp9
-rw-r--r--Source/WebCore/platform/graphics/filters/FETurbulence.cpp13
-rw-r--r--Source/WebCore/platform/graphics/filters/arm/FECompositeArithmeticNEON.h2
-rw-r--r--Source/WebCore/platform/graphics/filters/arm/FEGaussianBlurNEON.h15
-rw-r--r--Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h2
-rw-r--r--Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp6
-rw-r--r--Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp46
-rw-r--r--Source/WebCore/platform/graphics/glx/GLContextGLX.cpp98
-rw-r--r--Source/WebCore/platform/graphics/glx/GLContextGLX.h8
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp5
-rw-r--r--Source/WebCore/platform/graphics/gpu/DrawingBuffer.h2
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp6
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h1
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp9
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h3
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h4
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp5
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp8
-rw-r--r--Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp14
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp5
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp4
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/HarfBuzzSkia.cpp12
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp83
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h9
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp6
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp9
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp60
-rw-r--r--Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp59
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.cpp33
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextController.h4
-rw-r--r--Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm4
-rw-r--r--Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp14
-rw-r--r--Source/WebCore/platform/graphics/mac/FontCacheMac.mm14
-rw-r--r--Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp11
-rw-r--r--Source/WebCore/platform/graphics/mac/FontMac.mm8
-rw-r--r--Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm6
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h4
-rw-r--r--Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm17
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp2
-rw-r--r--Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm24
-rw-r--r--Source/WebCore/platform/graphics/mac/WebLayer.mm4
-rw-r--r--Source/WebCore/platform/graphics/mac/WebTiledLayer.mm2
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp59
-rw-r--r--Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h16
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp34
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp96
-rw-r--r--Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp42
-rw-r--r--Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp21
-rw-r--r--Source/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp12
-rw-r--r--Source/WebCore/platform/graphics/pango/FontCachePango.cpp6
-rw-r--r--Source/WebCore/platform/graphics/pango/FontPango.cpp2
-rw-r--r--Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp12
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCacheQt.cpp8
-rw-r--r--Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp34
-rw-r--r--Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp11
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h6
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp151
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp6
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageDecoderQt.h6
-rw-r--r--Source/WebCore/platform/graphics/qt/ImageQt.cpp90
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp142
-rw-r--r--Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h21
-rw-r--r--Source/WebCore/platform/graphics/qt/PathQt.cpp9
-rw-r--r--Source/WebCore/platform/graphics/qt/PatternQt.cpp6
-rw-r--r--Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp12
-rw-r--r--Source/WebCore/platform/graphics/qt/StillImageQt.cpp28
-rw-r--r--Source/WebCore/platform/graphics/qt/StillImageQt.h16
-rw-r--r--Source/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp2
-rw-r--r--Source/WebCore/platform/graphics/qt/TransparencyLayer.h14
-rw-r--r--Source/WebCore/platform/graphics/skia/FontCacheSkia.cpp12
-rw-r--r--Source/WebCore/platform/graphics/skia/FontSkia.cpp15
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp247
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp11
-rw-r--r--Source/WebCore/platform/graphics/skia/ImageSkia.cpp289
-rw-r--r--Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp (renamed from Source/WebCore/platform/text/LocalizedNumberICU.cpp)35
-rw-r--r--Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h (renamed from Source/WebCore/platform/text/LocalizedNumberNone.cpp)37
-rw-r--r--Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp114
-rw-r--r--Source/WebCore/platform/graphics/skia/NativeImageSkia.h58
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp1
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.h4
-rw-r--r--Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp57
-rw-r--r--Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp4
-rw-r--r--Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h12
-rw-r--r--Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h80
-rw-r--r--Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp25
-rw-r--r--Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp18
-rw-r--r--Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp3
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp19
-rw-r--r--Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h4
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapper.h5
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp4
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h5
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp366
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperGL.h18
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h2
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp20
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h6
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h6
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp939
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h251
-rw-r--r--Source/WebCore/platform/graphics/win/FontCGWin.cpp8
-rw-r--r--Source/WebCore/platform/graphics/win/FontCacheWin.cpp32
-rw-r--r--Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp2
-rw-r--r--Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp14
-rw-r--r--Source/WebCore/platform/graphics/wince/FontCacheWinCE.cpp20
-rw-r--r--Source/WebCore/platform/graphics/wince/FontPlatformData.cpp9
-rw-r--r--Source/WebCore/platform/graphics/wince/FontPlatformData.h1
-rw-r--r--Source/WebCore/platform/graphics/wince/FontWinCE.cpp3
-rw-r--r--Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp10
-rw-r--r--Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp14
-rw-r--r--Source/WebCore/platform/graphics/wx/FontCacheWx.cpp18
-rw-r--r--Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp12
-rw-r--r--Source/WebCore/platform/gtk/AsyncFileSystemGtk.cpp3
-rw-r--r--Source/WebCore/platform/gtk/ClipboardGtk.cpp8
-rw-r--r--Source/WebCore/platform/gtk/ClipboardGtk.h2
-rw-r--r--Source/WebCore/platform/gtk/DataObjectGtk.cpp2
-rw-r--r--Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp10
-rw-r--r--Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp151
-rw-r--r--Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h25
-rw-r--r--Source/WebCore/platform/gtk/RenderThemeGtk3.cpp6
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.h2
-rw-r--r--Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp6
-rw-r--r--Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp23
-rw-r--r--Source/WebCore/platform/leveldb/LevelDBTransaction.cpp6
-rw-r--r--Source/WebCore/platform/mac/ClipboardMac.h2
-rw-r--r--Source/WebCore/platform/mac/ClipboardMac.mm12
-rw-r--r--Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h1
-rw-r--r--Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm12
-rw-r--r--Source/WebCore/platform/mac/PasteboardMac.mm3
-rw-r--r--Source/WebCore/platform/mac/ScrollbarThemeMac.mm6
-rw-r--r--Source/WebCore/platform/mac/WebCoreSystemInterface.h14
-rw-r--r--Source/WebCore/platform/mac/WebCoreSystemInterface.mm7
-rw-r--r--Source/WebCore/platform/mediastream/MediaConstraints.h15
-rw-r--r--Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.cpp82
-rw-r--r--Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.h97
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp30
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h9
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCStatsRequest.h64
-rw-r--r--Source/WebCore/platform/mediastream/RTCStatsResponseBase.h50
-rw-r--r--Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.cpp56
-rw-r--r--Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.h10
-rw-r--r--Source/WebCore/platform/network/CredentialStorage.cpp4
-rw-r--r--Source/WebCore/platform/network/DataURL.cpp2
-rw-r--r--Source/WebCore/platform/network/HTTPHeaderMap.cpp4
-rw-r--r--Source/WebCore/platform/network/MIMEHeader.cpp6
-rw-r--r--Source/WebCore/platform/network/NetworkingContext.h1
-rw-r--r--Source/WebCore/platform/network/ResourceHandle.cpp2
-rw-r--r--Source/WebCore/platform/network/ResourceHandle.h3
-rw-r--r--Source/WebCore/platform/network/ResourceHandleInternal.h2
-rw-r--r--Source/WebCore/platform/network/ResourceLoadTiming.cpp9
-rw-r--r--Source/WebCore/platform/network/ResourceLoadTiming.h2
-rw-r--r--Source/WebCore/platform/network/ResourceRequestBase.cpp11
-rw-r--r--Source/WebCore/platform/network/ResourceResponseBase.cpp4
-rw-r--r--Source/WebCore/platform/network/blackberry/DNSBlackBerry.cpp2
-rw-r--r--Source/WebCore/platform/network/blackberry/NetworkJob.cpp142
-rw-r--r--Source/WebCore/platform/network/blackberry/NetworkJob.h7
-rw-r--r--Source/WebCore/platform/network/blackberry/NetworkManager.cpp13
-rw-r--r--Source/WebCore/platform/network/blackberry/ResourceRequestBlackBerry.cpp19
-rw-r--r--Source/WebCore/platform/network/blackberry/SocketStreamHandle.h2
-rw-r--r--Source/WebCore/platform/network/blackberry/SocketStreamHandleBlackBerry.cpp6
-rw-r--r--Source/WebCore/platform/network/cf/ResourceError.h1
-rw-r--r--Source/WebCore/platform/network/cf/ResourceErrorCF.cpp5
-rw-r--r--Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp2
-rw-r--r--Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp4
-rw-r--r--Source/WebCore/platform/network/curl/ResourceHandleManager.cpp4
-rw-r--r--Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp11
-rw-r--r--Source/WebCore/platform/network/mac/ResourceErrorMac.mm45
-rw-r--r--Source/WebCore/platform/network/mac/ResourceRequestMac.mm2
-rw-r--r--Source/WebCore/platform/network/qt/DnsPrefetchHelper.h2
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp143
-rw-r--r--Source/WebCore/platform/network/qt/QNetworkReplyHandler.h2
-rw-r--r--Source/WebCore/platform/network/qt/ResourceHandleQt.cpp4
-rw-r--r--Source/WebCore/platform/network/qt/ResourceRequestQt.cpp4
-rw-r--r--Source/WebCore/platform/network/soup/ResourceError.h18
-rw-r--r--Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp78
-rw-r--r--Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp294
-rw-r--r--Source/WebCore/platform/network/soup/ResourceRequest.h2
-rw-r--r--Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp11
-rw-r--r--Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp2
-rw-r--r--Source/WebCore/platform/network/win/ResourceHandleWin.cpp6
-rw-r--r--Source/WebCore/platform/qt/ClipboardQt.cpp17
-rw-r--r--Source/WebCore/platform/qt/ClipboardQt.h2
-rw-r--r--Source/WebCore/platform/qt/CursorQt.cpp7
-rw-r--r--Source/WebCore/platform/qt/DragImageQt.cpp4
-rw-r--r--Source/WebCore/platform/qt/GamepadsQt.cpp2
-rw-r--r--Source/WebCore/platform/qt/PasteboardQt.cpp8
-rw-r--r--Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp94
-rw-r--r--Source/WebCore/platform/qt/PlatformScreenQt.cpp2
-rw-r--r--Source/WebCore/platform/qt/QStyleFacade.cpp46
-rw-r--r--Source/WebCore/platform/qt/QStyleFacade.h201
-rw-r--r--Source/WebCore/platform/qt/RenderThemeQStyle.cpp620
-rw-r--r--Source/WebCore/platform/qt/RenderThemeQStyle.h158
-rw-r--r--Source/WebCore/platform/qt/RenderThemeQt.cpp2
-rw-r--r--Source/WebCore/platform/qt/RunLoopQt.cpp2
-rw-r--r--Source/WebCore/platform/qt/ScrollbarThemeQStyle.cpp221
-rw-r--r--Source/WebCore/platform/qt/ScrollbarThemeQStyle.h (renamed from Source/WebCore/platform/text/LocalizedDateNone.cpp)48
-rw-r--r--Source/WebCore/platform/sql/SQLiteDatabase.cpp13
-rw-r--r--Source/WebCore/platform/sql/SQLiteDatabase.h5
-rw-r--r--Source/WebCore/platform/sql/SQLiteStatement.cpp5
-rw-r--r--Source/WebCore/platform/text/DateTimeFormat.cpp6
-rw-r--r--Source/WebCore/platform/text/DateTimeFormat.h6
-rw-r--r--Source/WebCore/platform/text/LocaleICU.cpp59
-rw-r--r--Source/WebCore/platform/text/LocaleICU.h24
-rw-r--r--Source/WebCore/platform/text/LocaleNone.cpp32
-rw-r--r--Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp4
-rw-r--r--Source/WebCore/platform/text/LocaleWin.cpp225
-rw-r--r--Source/WebCore/platform/text/LocaleWin.h22
-rw-r--r--Source/WebCore/platform/text/LocalizedDate.h67
-rw-r--r--Source/WebCore/platform/text/LocalizedDateICU.cpp95
-rw-r--r--Source/WebCore/platform/text/LocalizedDateWin.cpp95
-rw-r--r--Source/WebCore/platform/text/LocalizedNumber.h58
-rw-r--r--Source/WebCore/platform/text/Localizer.cpp174
-rw-r--r--Source/WebCore/platform/text/Localizer.h84
-rw-r--r--Source/WebCore/platform/text/TextBreakIterator.cpp10
-rw-r--r--Source/WebCore/platform/text/TextBreakIterator.h26
-rw-r--r--Source/WebCore/platform/text/TextBreakIteratorICU.cpp228
-rw-r--r--Source/WebCore/platform/text/TextEncodingRegistry.cpp6
-rw-r--r--Source/WebCore/platform/text/blackberry/StringBlackBerry.cpp22
-rw-r--r--Source/WebCore/platform/text/blackberry/TextBreakIteratorInternalICUBlackBerry.cpp1
-rw-r--r--Source/WebCore/platform/text/mac/LocaleMac.h27
-rw-r--r--Source/WebCore/platform/text/mac/LocaleMac.mm91
-rw-r--r--Source/WebCore/platform/text/mac/LocalizedDateMac.cpp95
-rw-r--r--Source/WebCore/platform/text/qt/TextBoundariesQt.cpp4
-rw-r--r--Source/WebCore/platform/text/transcoder/FontTranscoder.cpp2
-rw-r--r--Source/WebCore/platform/text/win/LocalizedNumberWin.cpp49
-rw-r--r--Source/WebCore/platform/text/win/TextCodecWin.cpp20
-rw-r--r--Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp6
-rw-r--r--Source/WebCore/platform/win/ClipboardWin.cpp10
-rw-r--r--Source/WebCore/platform/win/ClipboardWin.h2
-rw-r--r--Source/WebCore/platform/win/FileSystemWin.cpp2
-rw-r--r--Source/WebCore/platform/win/RunLoopWin.cpp2
-rw-r--r--Source/WebCore/platform/win/WCDataObject.cpp2
-rw-r--r--Source/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp4
-rw-r--r--Source/WebCore/platform/wx/ClipboardWx.cpp4
-rw-r--r--Source/WebCore/platform/wx/ClipboardWx.h2
-rw-r--r--Source/WebCore/platform/wx/ContextMenuWx.cpp4
-rw-r--r--Source/WebCore/platform/wx/wxcode/cairo/non-kerned-drawing.cpp4
440 files changed, 9613 insertions, 6670 deletions
diff --git a/Source/WebCore/platform/AsyncFileSystem.cpp b/Source/WebCore/platform/AsyncFileSystem.cpp
index 29f1e232a..186642f85 100644
--- a/Source/WebCore/platform/AsyncFileSystem.cpp
+++ b/Source/WebCore/platform/AsyncFileSystem.cpp
@@ -39,15 +39,14 @@
namespace WebCore {
-#if !PLATFORM(CHROMIUM) && !PLATFORM(GTK) && !PLATFORM(BLACKBERRY)
+#if !PLATFORM(CHROMIUM) && !PLATFORM(GTK) && !PLATFORM(BLACKBERRY) && !PLATFORM(EFL)
bool AsyncFileSystem::isAvailable()
{
notImplemented();
return false;
}
-// FIXME: Add FileSystemType parameter.
-void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
notImplemented();
callbacks->didFail(NOT_SUPPORTED_ERR);
diff --git a/Source/WebCore/platform/AsyncFileSystem.h b/Source/WebCore/platform/AsyncFileSystem.h
index b087790d8..af5c51232 100644
--- a/Source/WebCore/platform/AsyncFileSystem.h
+++ b/Source/WebCore/platform/AsyncFileSystem.h
@@ -64,8 +64,7 @@ public:
static PassOwnPtr<AsyncFileSystem> create();
// Opens a new file system. The create parameter specifies whether or not to create the path if it does not already exists.
- // FIXME: Add FileSystemType parameter.
- static void openFileSystem(const String& basePath, const String& storageIdentifier, bool create, PassOwnPtr<AsyncFileSystemCallbacks>);
+ static void openFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, bool create, PassOwnPtr<AsyncFileSystemCallbacks>);
// Deletes the file system.
static void deleteFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, PassOwnPtr<AsyncFileSystemCallbacks>);
diff --git a/Source/WebCore/platform/DateComponents.cpp b/Source/WebCore/platform/DateComponents.cpp
index 670ffff21..320d723cb 100644
--- a/Source/WebCore/platform/DateComponents.cpp
+++ b/Source/WebCore/platform/DateComponents.cpp
@@ -41,12 +41,12 @@ using namespace std;
namespace WebCore {
-// HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in
-// 1582. However, we need to support 0001-01-01 in Gregorian calendar rule.
-static const int minimumYear = 1;
-// Date in ECMAScript can't represent dates later than 275760-09-13T00:00Z.
-// So, we have the same upper limit in HTML5 dates.
-static const int maximumYear = 275760;
+// HTML5 specification defines minimum week of year is one.
+const int DateComponents::minimumWeekNumber = 1;
+
+// HTML5 specification defines maximum week of year is 53.
+const int DateComponents::maximumWeekNumber = 53;
+
static const int maximumMonthInMaximumYear = 8; // This is September, since months are 0 based.
static const int maximumDayInMaximumMonth = 13;
static const int maximumWeekInMaximumYear = 37; // The week of 275760-09-13
@@ -95,7 +95,7 @@ static int dayOfWeek(int year, int month, int day)
int DateComponents::maxWeekNumberInYear() const
{
int day = dayOfWeek(m_year, 0, 1); // January 1.
- return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? 53 : 52;
+ return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? maximumWeekNumber : maximumWeekNumber - 1;
}
static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
@@ -139,7 +139,7 @@ bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start
int year;
if (!toInt(src, length, start, digitsLength, year))
return false;
- if (year < minimumYear || year > maximumYear)
+ if (year < minimumYear() || year > maximumYear())
return false;
m_year = year;
end = start + digitsLength;
@@ -148,18 +148,18 @@ bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start
static bool withinHTMLDateLimits(int year, int month)
{
- if (year < minimumYear)
+ if (year < DateComponents::minimumYear())
return false;
- if (year < maximumYear)
+ if (year < DateComponents::maximumYear())
return true;
return month <= maximumMonthInMaximumYear;
}
static bool withinHTMLDateLimits(int year, int month, int monthDay)
{
- if (year < minimumYear)
+ if (year < DateComponents::minimumYear())
return false;
- if (year < maximumYear)
+ if (year < DateComponents::maximumYear())
return true;
if (month < maximumMonthInMaximumYear)
return true;
@@ -168,9 +168,9 @@ static bool withinHTMLDateLimits(int year, int month, int monthDay)
static bool withinHTMLDateLimits(int year, int month, int monthDay, int hour, int minute, int second, int millisecond)
{
- if (year < minimumYear)
+ if (year < DateComponents::minimumYear())
return false;
- if (year < maximumYear)
+ if (year < DateComponents::maximumYear())
return true;
if (month < maximumMonthInMaximumYear)
return true;
@@ -394,9 +394,9 @@ bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start
++index;
int week;
- if (!toInt(src, length, index, 2, week) || week < 1 || week > maxWeekNumberInYear())
+ if (!toInt(src, length, index, 2, week) || week < minimumWeekNumber || week > maxWeekNumberInYear())
return false;
- if (m_year == maximumYear && week > maximumWeekInMaximumYear)
+ if (m_year == maximumYear() && week > maximumWeekInMaximumYear)
return false;
m_week = week;
end = index + 2;
@@ -592,7 +592,7 @@ bool DateComponents::setMonthsSinceEpoch(double months)
months = round(months);
double doubleMonth = positiveFmod(months, 12);
double doubleYear = 1970 + (months - doubleMonth) / 12;
- if (doubleYear < minimumYear || maximumYear < doubleYear)
+ if (doubleYear < minimumYear() || maximumYear() < doubleYear)
return false;
int year = static_cast<int>(doubleYear);
int month = static_cast<int>(doubleMonth);
@@ -622,7 +622,7 @@ bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
ms = round(ms);
m_year = msToYear(ms);
- if (m_year < minimumYear || m_year > maximumYear)
+ if (m_year < minimumYear() || m_year > maximumYear())
return false;
int yearDay = dayInYear(ms, m_year);
@@ -630,7 +630,7 @@ bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
if (yearDay < offset) {
// The day belongs to the last week of the previous year.
m_year--;
- if (m_year <= minimumYear)
+ if (m_year <= minimumYear())
return false;
m_week = maxWeekNumberInYear();
} else {
@@ -639,7 +639,7 @@ bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
m_year++;
m_week = 1;
}
- if (m_year > maximumYear || (m_year == maximumYear && m_week > maximumWeekInMaximumYear))
+ if (m_year > maximumYear() || (m_year == maximumYear() && m_week > maximumWeekInMaximumYear))
return false;
}
m_type = Week;
diff --git a/Source/WebCore/platform/DateComponents.h b/Source/WebCore/platform/DateComponents.h
index fdb268267..b7f6950d9 100644
--- a/Source/WebCore/platform/DateComponents.h
+++ b/Source/WebCore/platform/DateComponents.h
@@ -159,6 +159,15 @@ public:
static inline double maximumTime() { return 86399999; } // 23:59:59.999
static inline double maximumWeek() { return 8639999568000000.0; } // 275760-09-08, the Monday of the week including 275760-09-13.
+ // HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in
+ // 1582. However, we need to support 0001-01-01 in Gregorian calendar rule.
+ static inline int minimumYear() { return 1; }
+ // Date in ECMAScript can't represent dates later than 275760-09-13T00:00Z.
+ // So, we have the same upper limit in HTML5 date/time types.
+ static inline int maximumYear() { return 275760; }
+ static const int minimumWeekNumber;
+ static const int maximumWeekNumber;
+
private:
// Returns the maximum week number in this DateComponents's year.
// The result is either of 52 and 53.
diff --git a/Source/WebCore/platform/DateTimeChooser.h b/Source/WebCore/platform/DateTimeChooser.h
index 6c98e3f17..86ab13c6f 100644
--- a/Source/WebCore/platform/DateTimeChooser.h
+++ b/Source/WebCore/platform/DateTimeChooser.h
@@ -46,7 +46,9 @@ struct DateTimeChooserParameters {
double minimum;
double maximum;
double step;
+ double stepBase;
bool required;
+ bool isAnchorElementRTL;
};
// For pickers like color pickers and date pickers.
diff --git a/Source/WebCore/platform/DragImage.h b/Source/WebCore/platform/DragImage.h
index e78a9d3a8..dd970d293 100644
--- a/Source/WebCore/platform/DragImage.h
+++ b/Source/WebCore/platform/DragImage.h
@@ -36,7 +36,7 @@
OBJC_CLASS NSImage;
#elif PLATFORM(QT)
QT_BEGIN_NAMESPACE
-class QImage;
+class QPixmap;
QT_END_NAMESPACE
#elif PLATFORM(WIN)
typedef struct HBITMAP__* HBITMAP;
@@ -62,7 +62,7 @@ namespace WebCore {
#if PLATFORM(MAC)
typedef RetainPtr<NSImage> DragImageRef;
#elif PLATFORM(QT)
- typedef QImage* DragImageRef;
+ typedef QPixmap* DragImageRef;
#elif PLATFORM(WIN)
typedef HBITMAP DragImageRef;
#elif PLATFORM(WX)
diff --git a/Source/WebCore/platform/FractionalLayoutUnit.h b/Source/WebCore/platform/FractionalLayoutUnit.h
index 06be89787..0699b0649 100644
--- a/Source/WebCore/platform/FractionalLayoutUnit.h
+++ b/Source/WebCore/platform/FractionalLayoutUnit.h
@@ -38,10 +38,6 @@
#include <wtf/MathExtras.h>
#include <wtf/SaturatedArithmetic.h>
-#if PLATFORM(QT)
-#include <QDataStream>
-#endif
-
namespace WebCore {
#ifdef NDEBUG
@@ -59,7 +55,7 @@ while (0)
#endif
#if ENABLE(SUBPIXEL_LAYOUT)
-static const int kFixedPointDenominator = 60;
+static const int kFixedPointDenominator = 64;
#else
static const int kFixedPointDenominator = 1;
#endif
@@ -80,7 +76,7 @@ public:
FractionalLayoutUnit(float value)
{
#if ENABLE(SATURATED_LAYOUT_ARITHMETIC)
- m_value = clampTo<float>(value * kFixedPointDenominator, INT_MIN, INT_MAX);
+ m_value = clampTo<float>(value * kFixedPointDenominator, static_cast<float>(INT_MIN), static_cast<float>(INT_MAX));
#else
REPORT_OVERFLOW(isInBounds(value));
m_value = value * kFixedPointDenominator;
@@ -89,7 +85,7 @@ public:
FractionalLayoutUnit(double value)
{
#if ENABLE(SATURATED_LAYOUT_ARITHMETIC)
- m_value = clampTo<double>(value * kFixedPointDenominator, INT_MIN, INT_MAX);
+ m_value = clampTo<double>(value * kFixedPointDenominator, static_cast<double>(INT_MIN), static_cast<double>(INT_MAX));
#else
REPORT_OVERFLOW(isInBounds(value));
m_value = value * kFixedPointDenominator;
@@ -207,7 +203,11 @@ public:
}
int round() const
{
-#if ENABLE(SUBPIXEL_LAYOUT)
+#if ENABLE(SUBPIXEL_LAYOUT) && ENABLE(SATURATED_LAYOUT_ARITHMETIC)
+ if (m_value > 0)
+ return saturatedAddition(rawValue(), kFixedPointDenominator / 2) / kFixedPointDenominator;
+ return saturatedSubtraction(rawValue(), kFixedPointDenominator / 2) / kFixedPointDenominator;
+#elif ENABLE(SUBPIXEL_LAYOUT)
if (m_value > 0)
return (m_value + (kFixedPointDenominator / 2)) / kFixedPointDenominator;
return (m_value - (kFixedPointDenominator / 2)) / kFixedPointDenominator;
@@ -290,9 +290,9 @@ private:
inline void setValue(int value)
{
#if ENABLE(SATURATED_LAYOUT_ARITHMETIC)
- if (value >= intMaxForLayoutUnit)
+ if (value > intMaxForLayoutUnit)
m_value = std::numeric_limits<int>::max();
- else if (value <= intMinForLayoutUnit)
+ else if (value < intMinForLayoutUnit)
m_value = std::numeric_limits<int>::min();
else
m_value = value * kFixedPointDenominator;
@@ -820,26 +820,6 @@ inline int snapSizeToPixel(FractionalLayoutUnit size, FractionalLayoutUnit locat
return (fraction + size).round() - fraction.round();
}
-#if PLATFORM(QT)
-inline QDataStream& operator<<(QDataStream& stream, const FractionalLayoutUnit& value)
-{
- if (kFixedPointDenominator == 1)
- stream << value.rawValue();
- else
- stream << QString::fromLatin1("%1").arg(value.toFloat(), 0, 'f', 2);
-
- return stream;
-}
-
-inline QDataStream& operator>>(QDataStream& stream, FractionalLayoutUnit& value)
-{
- float v;
- stream >> v;
- value = v;
- return stream;
-}
-#endif
-
} // namespace WebCore
#endif // FractionalLayoutUnit_h
diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp
index c3d5099f3..0d2a6d8b3 100644
--- a/Source/WebCore/platform/KURL.cpp
+++ b/Source/WebCore/platform/KURL.cpp
@@ -35,6 +35,7 @@
#if !USE(WTFURL)
#include <wtf/HexNumber.h>
#endif
+#include <wtf/MemoryInstrumentationString.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
diff --git a/Source/WebCore/platform/KURLGoogle.cpp b/Source/WebCore/platform/KURLGoogle.cpp
index 6f8142672..c9266ee67 100644
--- a/Source/WebCore/platform/KURLGoogle.cpp
+++ b/Source/WebCore/platform/KURLGoogle.cpp
@@ -44,6 +44,7 @@
#include "PlatformMemoryInstrumentation.h"
#include "TextEncoding.h"
#include <wtf/HashMap.h>
+#include <wtf/MemoryInstrumentationString.h>
#include <wtf/Vector.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
diff --git a/Source/WebCore/platform/KURLWTFURL.cpp b/Source/WebCore/platform/KURLWTFURL.cpp
index 9a3484d41..4d30680ff 100644
--- a/Source/WebCore/platform/KURLWTFURL.cpp
+++ b/Source/WebCore/platform/KURLWTFURL.cpp
@@ -175,7 +175,7 @@ bool KURL::hasPort() const
if (!isValid())
return false;
- return !m_urlImpl->m_parsedURL.port().isNull();
+ return m_urlImpl->m_parsedURL.hasPort();
}
unsigned short KURL::port() const
@@ -313,8 +313,11 @@ void KURL::setHost(const String&)
void KURL::removePort()
{
+ if (!hasPort())
+ return;
+
detach(m_urlImpl);
- // FIXME: Add WTFURL Implementation.
+ m_urlImpl->m_parsedURL.removePort();
}
void KURL::setPort(unsigned short)
@@ -423,8 +426,9 @@ void KURL::invalidate()
bool KURL::isHierarchical() const
{
- // FIXME: Add WTFURL Implementation.
- return false;
+ if (!isValid())
+ return false;
+ return m_urlImpl->m_parsedURL.hasStandardScheme();
}
bool protocolIs(const String&, const char*)
diff --git a/Source/WebCore/platform/KURLWTFURLImpl.h b/Source/WebCore/platform/KURLWTFURLImpl.h
index c42487f4d..34c65be08 100644
--- a/Source/WebCore/platform/KURLWTFURLImpl.h
+++ b/Source/WebCore/platform/KURLWTFURLImpl.h
@@ -29,6 +29,7 @@
#if USE(WTFURL)
#include "PlatformMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationParsedURL.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -44,7 +45,7 @@ public:
void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
- typename MemoryObjectInfo::ClassInfo info(memoryObjectInfo, this);
+ MemoryClassInfo info(memoryObjectInfo, this);
info.addMember(m_parsedURL);
info.addMember(m_invalidUrlString);
}
diff --git a/Source/WebCore/platform/Language.cpp b/Source/WebCore/platform/Language.cpp
index 2af2a206e..dba3a89fb 100644
--- a/Source/WebCore/platform/Language.cpp
+++ b/Source/WebCore/platform/Language.cpp
@@ -53,7 +53,7 @@ void languageDidChange()
{
ObserverMap::iterator end = observerMap().end();
for (ObserverMap::iterator iter = observerMap().begin(); iter != end; ++iter)
- iter->second(iter->first);
+ iter->value(iter->key);
}
String defaultLanguage()
diff --git a/Source/WebCore/platform/LocalizedStrings.h b/Source/WebCore/platform/LocalizedStrings.h
index 39f112bb7..83432cf79 100644
--- a/Source/WebCore/platform/LocalizedStrings.h
+++ b/Source/WebCore/platform/LocalizedStrings.h
@@ -165,7 +165,7 @@ namespace WebCore {
String AXMenuListPopupActionVerb();
String AXLinkActionVerb();
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String AXAMPMFieldText();
String AXDayOfMonthFieldText();
String AXDateTimeFieldEmptyValueText();
@@ -176,6 +176,31 @@ namespace WebCore {
String AXSecondFieldText();
String AXWeekOfYearFieldText();
String AXYearFieldText();
+
+ // placeholderForDayOfMonthField() returns localized placeholder text, e.g.
+ // "dd", for date field used in multiple fields "date", "datetime", and
+ // "datetime-local" input UI instead "--".
+ String placeholderForDayOfMonthField();
+
+ // placeholderForfMonthField() returns localized placeholder text, e.g.
+ // "mm", for month field used in multiple fields "date", "datetime", and
+ // "datetime-local" input UI instead "--".
+ String placeholderForMonthField();
+
+ // placeholderForYearField() returns localized placeholder text, e.g.
+ // "yyyy", for year field used in multiple fields "date", "datetime", and
+ // "datetime-local" input UI instead "----".
+ String placeholderForYearField();
+
+ // monthFormatInLDML() returns month and year format in LDML, Unicode
+ // technical standard 35, Locale Data Markup Language, e.g. "MM-yyyyy"
+ // for "month" input type.
+ String monthFormatInLDML();
+
+ // monthFormatInLDML() returns week and year format in LDML, Unicode
+ // technical standard 35, Locale Data Markup Language, e.g. "WW-yyyyy"
+ // for "week" input type.
+ String weekFormatInLDML();
#endif
String missingPluginText();
diff --git a/Source/WebCore/platform/MIMETypeRegistry.cpp b/Source/WebCore/platform/MIMETypeRegistry.cpp
index 0626170e0..440b4299a 100755
--- a/Source/WebCore/platform/MIMETypeRegistry.cpp
+++ b/Source/WebCore/platform/MIMETypeRegistry.cpp
@@ -579,6 +579,17 @@ bool MIMETypeRegistry::isJavaAppletMIMEType(const String& mimeType)
|| mimeType.startsWith("application/x-java-vm", false);
}
+bool MIMETypeRegistry::canShowMIMEType(const String& mimeType)
+{
+ if (isSupportedImageMIMEType(mimeType) || isSupportedNonImageMIMEType(mimeType) || isSupportedMediaMIMEType(mimeType))
+ return true;
+
+ if (mimeType.startsWith("text/", false))
+ return !MIMETypeRegistry::isUnsupportedTextMIMEType(mimeType);
+
+ return false;
+}
+
HashSet<String>& MIMETypeRegistry::getSupportedImageMIMETypes()
{
if (!supportedImageMIMETypes)
@@ -693,7 +704,7 @@ String MIMETypeRegistry::getNormalizedMIMEType(const String& mimeType)
MIMETypeAssociationMap::const_iterator it = mimeTypeAssociationMap().find(mimeType);
if (it != mimeTypeAssociationMap().end())
- return it->second;
+ return it->value;
#endif
return mimeType;
}
diff --git a/Source/WebCore/platform/MIMETypeRegistry.h b/Source/WebCore/platform/MIMETypeRegistry.h
index ab8b7ded1..5612b9223 100644
--- a/Source/WebCore/platform/MIMETypeRegistry.h
+++ b/Source/WebCore/platform/MIMETypeRegistry.h
@@ -78,6 +78,11 @@ public:
// browser (e.g. a Qt Plugin).
static bool isApplicationPluginMIMEType(const String& mimeType);
+ // Check to see if a mime type is suitable for being shown inside a page.
+ // Returns true if any of isSupportedImageMIMEType(), isSupportedNonImageMIMEType(), isSupportedMediaMIMEType() returns true
+ // or if given mime type begins with "text/" and isUnsupportedTextMIMEType() returns false.
+ static bool canShowMIMEType(const String& mimeType);
+
static HashSet<String>& getSupportedImageMIMETypes();
static HashSet<String>& getSupportedImageResourceMIMETypes();
static HashSet<String>& getSupportedImageMIMETypesForEncoding();
diff --git a/Source/WebCore/platform/MemoryPressureHandler.h b/Source/WebCore/platform/MemoryPressureHandler.h
index df62ca283..d894f841d 100644
--- a/Source/WebCore/platform/MemoryPressureHandler.h
+++ b/Source/WebCore/platform/MemoryPressureHandler.h
@@ -28,7 +28,6 @@
#include <time.h>
#include <wtf/FastAllocBase.h>
-#include <wtf/Platform.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/PlatformMemoryInstrumentation.h b/Source/WebCore/platform/PlatformMemoryInstrumentation.h
index 22b90974d..46a84bbd8 100644
--- a/Source/WebCore/platform/PlatformMemoryInstrumentation.h
+++ b/Source/WebCore/platform/PlatformMemoryInstrumentation.h
@@ -32,6 +32,7 @@
#define PlatformMemoryInstrumentation_h
#include <wtf/MemoryInstrumentation.h>
+#include <wtf/MemoryInstrumentationString.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/ScrollAnimatorNone.cpp b/Source/WebCore/platform/ScrollAnimatorNone.cpp
index 969d8aa09..04f26d27b 100644
--- a/Source/WebCore/platform/ScrollAnimatorNone.cpp
+++ b/Source/WebCore/platform/ScrollAnimatorNone.cpp
@@ -417,6 +417,40 @@ void ScrollAnimatorNone::fireUpAnAnimation(FloatPoint fp)
#endif
}
+ScrollAnimatorNone::Parameters ScrollAnimatorNone::parametersForScrollGranularity(ScrollGranularity granularity) const
+{
+#if !PLATFORM(QT)
+ switch (granularity) {
+ case ScrollByDocument:
+ return Parameters(true, 20 * kTickTime, 10 * kTickTime, Cubic, 10 * kTickTime, Cubic, 10 * kTickTime, Linear, 1);
+ case ScrollByLine:
+ return Parameters(true, 10 * kTickTime, 7 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Linear, 1);
+ case ScrollByPage:
+ return Parameters(true, 15 * kTickTime, 10 * kTickTime, Cubic, 5 * kTickTime, Cubic, 5 * kTickTime, Linear, 1);
+ case ScrollByPixel:
+ return Parameters(true, 11 * kTickTime, 2 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Quadratic, 1.25);
+ default:
+ ASSERT_NOT_REACHED();
+ }
+#else
+ // This is a slightly different strategy for the animation with a steep attack curve and natural release curve.
+ // The fast acceleration makes the animation look more responsive to user input.
+ switch (granularity) {
+ case ScrollByDocument:
+ return Parameters(true, 20 * kTickTime, 10 * kTickTime, Cubic, 6 * kTickTime, Quadratic, 10 * kTickTime, Quadratic, 22 * kTickTime);
+ case ScrollByLine:
+ return Parameters(true, 6 * kTickTime, 5 * kTickTime, Cubic, 1 * kTickTime, Quadratic, 4 * kTickTime, Linear, 1);
+ case ScrollByPage:
+ return Parameters(true, 12 * kTickTime, 10 * kTickTime, Cubic, 3 * kTickTime, Quadratic, 6 * kTickTime, Linear, 1);
+ case ScrollByPixel:
+ return Parameters(true, 8 * kTickTime, 3 * kTickTime, Cubic, 2 * kTickTime, Quadratic, 5 * kTickTime, Quadratic, 1.25);
+ default:
+ ASSERT_NOT_REACHED();
+ }
+#endif
+ return Parameters();
+}
+
bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
{
if (!m_scrollableArea->scrollAnimatorEnabled())
@@ -431,16 +465,10 @@ bool ScrollAnimatorNone::scroll(ScrollbarOrientation orientation, ScrollGranular
Parameters parameters;
switch (granularity) {
case ScrollByDocument:
- parameters = Parameters(true, 20 * kTickTime, 10 * kTickTime, Cubic, 10 * kTickTime, Cubic, 10 * kTickTime, Linear, 1);
- break;
case ScrollByLine:
- parameters = Parameters(true, 10 * kTickTime, 7 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Linear, 1);
- break;
case ScrollByPage:
- parameters = Parameters(true, 15 * kTickTime, 10 * kTickTime, Cubic, 5 * kTickTime, Cubic, 5 * kTickTime, Linear, 1);
- break;
case ScrollByPixel:
- parameters = Parameters(true, 11 * kTickTime, 2 * kTickTime, Cubic, 3 * kTickTime, Cubic, 3 * kTickTime, Quadratic, 1.25);
+ parameters = parametersForScrollGranularity(granularity);
break;
case ScrollByPrecisePixel:
return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
diff --git a/Source/WebCore/platform/ScrollAnimatorNone.h b/Source/WebCore/platform/ScrollAnimatorNone.h
index 2a4d86611..867df9741 100644
--- a/Source/WebCore/platform/ScrollAnimatorNone.h
+++ b/Source/WebCore/platform/ScrollAnimatorNone.h
@@ -104,6 +104,8 @@ protected:
virtual void animationWillStart() { }
virtual void animationDidFinish() { }
+ Parameters parametersForScrollGranularity(ScrollGranularity) const;
+
friend class ::ScrollAnimatorNoneTest;
struct PerAxisData {
diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h
index 2cbcc270e..a8cc7d011 100644
--- a/Source/WebCore/platform/ScrollView.h
+++ b/Source/WebCore/platform/ScrollView.h
@@ -184,7 +184,7 @@ public:
IntPoint cachedScrollPosition() const { return m_cachedScrollPosition; }
// Functions for scrolling the view.
- void setScrollPosition(const IntPoint&);
+ virtual void setScrollPosition(const IntPoint&);
void scrollBy(const IntSize& s) { return setScrollPosition(scrollPosition() + s); }
// This function scrolls by lines, pages or pixels.
diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h
index c744af6f0..930cdc00e 100644
--- a/Source/WebCore/platform/ScrollableArea.h
+++ b/Source/WebCore/platform/ScrollableArea.h
@@ -106,10 +106,10 @@ public:
virtual bool isActive() const = 0;
virtual int scrollSize(ScrollbarOrientation) const = 0;
virtual int scrollPosition(Scrollbar*) const = 0;
- void invalidateScrollbar(Scrollbar*, const IntRect&);
+ virtual void invalidateScrollbar(Scrollbar*, const IntRect&);
virtual bool isScrollCornerVisible() const = 0;
virtual IntRect scrollCornerRect() const = 0;
- void invalidateScrollCorner(const IntRect&);
+ virtual void invalidateScrollCorner(const IntRect&);
virtual void getTickmarks(Vector<IntRect>&) const { }
// Convert points and rects between the scrollbar and its containing view.
diff --git a/Source/WebCore/platform/SharedBuffer.cpp b/Source/WebCore/platform/SharedBuffer.cpp
index de5f71dc2..ed03a629e 100644
--- a/Source/WebCore/platform/SharedBuffer.cpp
+++ b/Source/WebCore/platform/SharedBuffer.cpp
@@ -148,6 +148,8 @@ void SharedBuffer::append(SharedBuffer* data)
void SharedBuffer::append(const char* data, unsigned length)
{
ASSERT(!m_purgeableBuffer);
+ if (!length)
+ return;
maybeTransferPlatformData();
diff --git a/Source/WebCore/platform/ThreadTimers.cpp b/Source/WebCore/platform/ThreadTimers.cpp
index 998dc32a6..4d8660518 100644
--- a/Source/WebCore/platform/ThreadTimers.cpp
+++ b/Source/WebCore/platform/ThreadTimers.cpp
@@ -106,6 +106,7 @@ void ThreadTimers::sharedTimerFiredInternal()
while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {
TimerBase* timer = m_timerHeap.first();
timer->m_nextFireTime = 0;
+ timer->m_unalignedNextFireTime = 0;
timer->heapDeleteMin();
double interval = timer->repeatInterval();
diff --git a/Source/WebCore/platform/Timer.cpp b/Source/WebCore/platform/Timer.cpp
index f2cf27192..f87971c7f 100644
--- a/Source/WebCore/platform/Timer.cpp
+++ b/Source/WebCore/platform/Timer.cpp
@@ -192,6 +192,7 @@ inline bool TimerHeapLessThanFunction::operator()(TimerBase* a, TimerBase* b) co
TimerBase::TimerBase()
: m_nextFireTime(0)
+ , m_unalignedNextFireTime(0)
, m_repeatInterval(0)
, m_heapIndex(-1)
#ifndef NDEBUG
@@ -312,12 +313,16 @@ void TimerBase::heapPopMin()
ASSERT(this == timerHeap().last());
}
-void TimerBase::setNextFireTime(double newTime)
+void TimerBase::setNextFireTime(double newUnalignedTime)
{
ASSERT(m_thread == currentThread());
+ if (m_unalignedNextFireTime != newUnalignedTime)
+ m_unalignedNextFireTime = newUnalignedTime;
+
// Keep heap valid while changing the next-fire time.
double oldTime = m_nextFireTime;
+ double newTime = alignedFireTime(newUnalignedTime);
if (oldTime != newTime) {
m_nextFireTime = newTime;
static unsigned currentHeapInsertionOrder;
@@ -349,5 +354,16 @@ void TimerBase::fireTimersInNestedEventLoop()
threadGlobalData().threadTimers().fireTimersInNestedEventLoop();
}
+void TimerBase::didChangeAlignmentInterval()
+{
+ setNextFireTime(m_unalignedNextFireTime);
+}
+
+double TimerBase::nextUnalignedFireInterval() const
+{
+ ASSERT(isActive());
+ return max(m_unalignedNextFireTime - monotonicallyIncreasingTime(), 0.0);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/Timer.h b/Source/WebCore/platform/Timer.h
index 3a5cd9d6f..c55789940 100644
--- a/Source/WebCore/platform/Timer.h
+++ b/Source/WebCore/platform/Timer.h
@@ -50,16 +50,21 @@ public:
bool isActive() const;
double nextFireInterval() const;
+ double nextUnalignedFireInterval() const;
double repeatInterval() const { return m_repeatInterval; }
void augmentFireInterval(double delta) { setNextFireTime(m_nextFireTime + delta); }
void augmentRepeatInterval(double delta) { augmentFireInterval(delta); m_repeatInterval += delta; }
+ void didChangeAlignmentInterval();
+
static void fireTimersInNestedEventLoop();
private:
virtual void fired() = 0;
+ virtual double alignedFireTime(double fireTime) const { return fireTime; }
+
void checkConsistency() const;
void checkHeapIndex() const;
@@ -76,6 +81,7 @@ private:
void heapPopMin();
double m_nextFireTime; // 0 if inactive
+ double m_unalignedNextFireTime; // m_nextFireTime not considering alignment interval
double m_repeatInterval; // 0 if not repeating
int m_heapIndex; // -1 if not in heap
unsigned m_heapInsertionOrder; // Used to keep order among equal-fire-time timers
diff --git a/Source/WebCore/platform/TouchFlingPlatformGestureCurve.cpp b/Source/WebCore/platform/TouchFlingPlatformGestureCurve.cpp
index e8d4875f1..ed37cf1d9 100644
--- a/Source/WebCore/platform/TouchFlingPlatformGestureCurve.cpp
+++ b/Source/WebCore/platform/TouchFlingPlatformGestureCurve.cpp
@@ -56,13 +56,13 @@ static const int cMaxSearchIterations = 20;
PassOwnPtr<PlatformGestureCurve> TouchFlingPlatformGestureCurve::createForTouchPad(const FloatPoint& velocity, IntPoint cumulativeScroll)
{
// The default parameters listed below are a matched set, and should not be changed independently of one another.
- return create(velocity, -1.5e+02, 10, 1.5e+00, 2.075, cumulativeScroll);
+ return create(velocity, -5.70762e+03, 1.72e+02, 3.7e+00, 1.3, cumulativeScroll);
}
PassOwnPtr<PlatformGestureCurve> TouchFlingPlatformGestureCurve::createForTouchScreen(const FloatPoint& velocity, IntPoint cumulativeScroll)
{
// The touchscreen-specific parameters listed below are a matched set, and should not be changed independently of one another.
- return create(velocity, -1.5e+02, 10, 1.5e+00, 2.075, cumulativeScroll);
+ return create(velocity, -5.70762e+03, 1.72e+02, 3.7e+00, 1.3, cumulativeScroll);
}
PassOwnPtr<PlatformGestureCurve> TouchFlingPlatformGestureCurve::create(const FloatPoint& velocity, float p0, float p1, float p2, float curveDuration, IntPoint cumulativeScroll)
diff --git a/Source/WebCore/platform/audio/AudioBus.cpp b/Source/WebCore/platform/audio/AudioBus.cpp
index 58a5e340d..bb7dad74c 100644
--- a/Source/WebCore/platform/audio/AudioBus.cpp
+++ b/Source/WebCore/platform/audio/AudioBus.cpp
@@ -76,6 +76,16 @@ void AudioBus::setChannelMemory(unsigned channelIndex, float* storage, size_t le
}
}
+void AudioBus::resizeSmaller(size_t newLength)
+{
+ ASSERT(newLength <= m_length);
+ if (newLength <= m_length)
+ m_length = newLength;
+
+ for (unsigned i = 0; i < m_channels.size(); ++i)
+ m_channels[i]->resizeSmaller(newLength);
+}
+
void AudioBus::zero()
{
for (unsigned i = 0; i < m_channels.size(); ++i)
diff --git a/Source/WebCore/platform/audio/AudioBus.h b/Source/WebCore/platform/audio/AudioBus.h
index b80a488a2..5c2451934 100644
--- a/Source/WebCore/platform/audio/AudioBus.h
+++ b/Source/WebCore/platform/audio/AudioBus.h
@@ -76,6 +76,10 @@ public:
// Number of sample-frames
size_t length() const { return m_length; }
+ // resizeSmaller() can only be called with a new length <= the current length.
+ // The data stored in the bus will remain undisturbed.
+ void resizeSmaller(size_t newLength);
+
// Sample-rate : 0.0 if unknown or "don't care"
float sampleRate() const { return m_sampleRate; }
void setSampleRate(float sampleRate) { m_sampleRate = sampleRate; }
diff --git a/Source/WebCore/platform/audio/AudioChannel.cpp b/Source/WebCore/platform/audio/AudioChannel.cpp
index 2321349bc..09f638fbd 100644
--- a/Source/WebCore/platform/audio/AudioChannel.cpp
+++ b/Source/WebCore/platform/audio/AudioChannel.cpp
@@ -41,6 +41,13 @@ namespace WebCore {
using namespace VectorMath;
+void AudioChannel::resizeSmaller(size_t newLength)
+{
+ ASSERT(newLength <= m_length);
+ if (newLength <= m_length)
+ m_length = newLength;
+}
+
void AudioChannel::scale(float scale)
{
if (isSilent())
@@ -65,15 +72,15 @@ void AudioChannel::copyFrom(const AudioChannel* sourceChannel)
void AudioChannel::copyFromRange(const AudioChannel* sourceChannel, unsigned startFrame, unsigned endFrame)
{
- if (sourceChannel->isSilent() && isSilent())
- return;
-
// Check that range is safe for reading from sourceChannel.
bool isRangeSafe = sourceChannel && startFrame < endFrame && endFrame <= sourceChannel->length();
ASSERT(isRangeSafe);
if (!isRangeSafe)
return;
+ if (sourceChannel->isSilent() && isSilent())
+ return;
+
// Check that this channel has enough space.
size_t rangeLength = endFrame - startFrame;
bool isRangeLengthSafe = rangeLength <= length();
@@ -95,14 +102,14 @@ void AudioChannel::copyFromRange(const AudioChannel* sourceChannel, unsigned sta
void AudioChannel::sumFrom(const AudioChannel* sourceChannel)
{
- if (sourceChannel->isSilent())
- return;
-
bool isSafe = sourceChannel && sourceChannel->length() >= length();
ASSERT(isSafe);
if (!isSafe)
return;
+ if (sourceChannel->isSilent())
+ return;
+
if (isSilent())
copyFrom(sourceChannel);
else
diff --git a/Source/WebCore/platform/audio/AudioChannel.h b/Source/WebCore/platform/audio/AudioChannel.h
index 4d277596f..266e7da8f 100644
--- a/Source/WebCore/platform/audio/AudioChannel.h
+++ b/Source/WebCore/platform/audio/AudioChannel.h
@@ -79,6 +79,10 @@ public:
// How many sample-frames do we contain?
size_t length() const { return m_length; }
+ // resizeSmaller() can only be called with a new length <= the current length.
+ // The data stored in the bus will remain undisturbed.
+ void resizeSmaller(size_t newLength);
+
// Direct access to PCM sample data. Non-const accessor clears silent flag.
float* mutableData()
{
diff --git a/Source/WebCore/platform/audio/EqualPowerPanner.cpp b/Source/WebCore/platform/audio/EqualPowerPanner.cpp
index 903536786..6b229f852 100644
--- a/Source/WebCore/platform/audio/EqualPowerPanner.cpp
+++ b/Source/WebCore/platform/audio/EqualPowerPanner.cpp
@@ -51,12 +51,13 @@ EqualPowerPanner::EqualPowerPanner(float sampleRate)
void EqualPowerPanner::pan(double azimuth, double /*elevation*/, const AudioBus* inputBus, AudioBus* outputBus, size_t framesToProcess)
{
- unsigned numberOfInputChannels = inputBus->numberOfChannels();
- bool isInputSafe = inputBus && (numberOfInputChannels == 1 || numberOfInputChannels == 2) && framesToProcess <= inputBus->length();
+ bool isInputSafe = inputBus && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2) && framesToProcess <= inputBus->length();
ASSERT(isInputSafe);
if (!isInputSafe)
return;
+ unsigned numberOfInputChannels = inputBus->numberOfChannels();
+
bool isOutputSafe = outputBus && outputBus->numberOfChannels() == 2 && framesToProcess <= outputBus->length();
ASSERT(isOutputSafe);
if (!isOutputSafe)
diff --git a/Source/WebCore/platform/audio/HRTFElevation.cpp b/Source/WebCore/platform/audio/HRTFElevation.cpp
index 25e458962..cfe13ed85 100644
--- a/Source/WebCore/platform/audio/HRTFElevation.cpp
+++ b/Source/WebCore/platform/audio/HRTFElevation.cpp
@@ -79,7 +79,7 @@ static AudioBus* getConcatenatedImpulseResponsesForSubject(const String& subject
bus = concatenatedImpulseResponses.leakPtr();
audioBusMap.set(subjectName, bus);
} else
- bus = iterator->second;
+ bus = iterator->value;
size_t responseLength = bus->length();
size_t expectedLength = static_cast<size_t>(TotalNumberOfResponses * ResponseFrameSize);
diff --git a/Source/WebCore/platform/audio/VectorMath.cpp b/Source/WebCore/platform/audio/VectorMath.cpp
index 60be4e0c1..bb20ceee6 100644
--- a/Source/WebCore/platform/audio/VectorMath.cpp
+++ b/Source/WebCore/platform/audio/VectorMath.cpp
@@ -36,6 +36,10 @@
#include <emmintrin.h>
#endif
+#if HAVE(ARM_NEON_INTRINSICS)
+#include <arm_neon.h>
+#endif
+
#include <algorithm>
#include <math.h>
@@ -107,6 +111,11 @@ void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesTo
{
vDSP_svesq(const_cast<float*>(sourceP), sourceStride, sumP, framesToProcess);
}
+
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess)
+{
+ vDSP_vclip(const_cast<float*>(sourceP), sourceStride, const_cast<float*>(lowThresholdP), const_cast<float*>(highThresholdP), destP, destStride, framesToProcess);
+}
#else
void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
@@ -155,6 +164,24 @@ void vsma(const float* sourceP, int sourceStride, const float* scale, float* des
n = tailFrames;
}
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if ((sourceStride == 1) && (destStride == 1)) {
+ int tailFrames = n % 4;
+ const float* endP = destP + n - tailFrames;
+
+ float32x4_t k = vdupq_n_f32(*scale);
+ while (destP < endP) {
+ float32x4_t source = vld1q_f32(sourceP);
+ float32x4_t dest = vld1q_f32(destP);
+
+ dest = vmlaq_f32(dest, source, k);
+ vst1q_f32(destP, dest);
+
+ sourceP += 4;
+ destP += 4;
+ }
+ n = tailFrames;
+ }
#endif
while (n) {
*destP += *sourceP * *scale;
@@ -166,10 +193,10 @@ void vsma(const float* sourceP, int sourceStride, const float* scale, float* des
void vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
{
+ int n = framesToProcess;
+
#ifdef __SSE2__
if ((sourceStride == 1) && (destStride == 1)) {
-
- int n = framesToProcess;
float k = *scale;
// If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
@@ -217,8 +244,22 @@ void vsmul(const float* sourceP, int sourceStride, const float* scale, float* de
n--;
}
} else { // If strides are not 1, rollback to normal algorithm.
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if ((sourceStride == 1) && (destStride == 1)) {
+ float k = *scale;
+ int tailFrames = n % 4;
+ const float* endP = destP + n - tailFrames;
+
+ while (destP < endP) {
+ float32x4_t source = vld1q_f32(sourceP);
+ vst1q_f32(destP, vmulq_n_f32(source, k));
+
+ sourceP += 4;
+ destP += 4;
+ }
+ n = tailFrames;
+ }
#endif
- int n = framesToProcess;
float k = *scale;
while (n--) {
*destP = k * *sourceP;
@@ -232,11 +273,10 @@ void vsmul(const float* sourceP, int sourceStride, const float* scale, float* de
void vadd(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess)
{
+ int n = framesToProcess;
+
#ifdef __SSE2__
if ((sourceStride1 ==1) && (sourceStride2 == 1) && (destStride == 1)) {
-
- int n = framesToProcess;
-
// If the sourceP address is not 16-byte aligned, the first several frames (at most three) should be processed separately.
while ((reinterpret_cast<size_t>(source1P) & 0x0F) && n) {
*destP = *source1P + *source2P;
@@ -315,8 +355,23 @@ void vadd(const float* source1P, int sourceStride1, const float* source2P, int s
n--;
}
} else { // if strides are not 1, rollback to normal algorithm
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if ((sourceStride1 ==1) && (sourceStride2 == 1) && (destStride == 1)) {
+ int tailFrames = n % 4;
+ const float* endP = destP + n - tailFrames;
+
+ while (destP < endP) {
+ float32x4_t source1 = vld1q_f32(source1P);
+ float32x4_t source2 = vld1q_f32(source2P);
+ vst1q_f32(destP, vaddq_f32(source1, source2));
+
+ source1P += 4;
+ source2P += 4;
+ destP += 4;
+ }
+ n = tailFrames;
+ }
#endif
- int n = framesToProcess;
while (n--) {
*destP = *source1P + *source2P;
source1P += sourceStride1;
@@ -377,6 +432,22 @@ void vmul(const float* source1P, int sourceStride1, const float* source2P, int s
n = tailFrames;
}
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if ((sourceStride1 ==1) && (sourceStride2 == 1) && (destStride == 1)) {
+ int tailFrames = n % 4;
+ const float* endP = destP + n - tailFrames;
+
+ while (destP < endP) {
+ float32x4_t source1 = vld1q_f32(source1P);
+ float32x4_t source2 = vld1q_f32(source2P);
+ vst1q_f32(destP, vmulq_f32(source1, source2));
+
+ source1P += 4;
+ source2P += 4;
+ destP += 4;
+ }
+ n = tailFrames;
+ }
#endif
while (n) {
*destP = *source1P * *source2P;
@@ -415,6 +486,22 @@ void zvmul(const float* real1P, const float* imag1P, const float* real2P, const
i += 4;
}
}
+#elif HAVE(ARM_NEON_INTRINSICS)
+ unsigned endSize = framesToProcess - framesToProcess % 4;
+ while (i < endSize) {
+ float32x4_t real1 = vld1q_f32(real1P + i);
+ float32x4_t real2 = vld1q_f32(real2P + i);
+ float32x4_t imag1 = vld1q_f32(imag1P + i);
+ float32x4_t imag2 = vld1q_f32(imag2P + i);
+
+ float32x4_t realResult = vmlsq_f32(vmulq_f32(real1, real2), imag1, imag2);
+ float32x4_t imagResult = vmlaq_f32(vmulq_f32(real1, imag2), imag1, real2);
+
+ vst1q_f32(realDestP + i, realResult);
+ vst1q_f32(imagDestP + i, imagResult);
+
+ i += 4;
+ }
#endif
for (; i < framesToProcess; ++i) {
// Read and compute result before storing them, in case the
@@ -461,6 +548,25 @@ void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesTo
n = tailFrames;
}
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if (sourceStride == 1) {
+ int tailFrames = n % 4;
+ const float* endP = sourceP + n - tailFrames;
+
+ float32x4_t fourSum = vdupq_n_f32(0);
+ while (sourceP < endP) {
+ float32x4_t source = vld1q_f32(sourceP);
+ fourSum = vmlaq_f32(fourSum, source, source);
+ sourceP += 4;
+ }
+ float32x2_t twoSum = vadd_f32(vget_low_f32(fourSum), vget_high_f32(fourSum));
+
+ float groupSum[2];
+ vst1_f32(groupSum, twoSum);
+ sum += groupSum[0] + groupSum[1];
+
+ n = tailFrames;
+ }
#endif
while (n--) {
@@ -512,6 +618,25 @@ void vmaxmgv(const float* sourceP, int sourceStride, float* maxP, size_t framesT
n = tailFrames;
}
+#elif HAVE(ARM_NEON_INTRINSICS)
+ if (sourceStride == 1) {
+ int tailFrames = n % 4;
+ const float* endP = sourceP + n - tailFrames;
+
+ float32x4_t fourMax = vdupq_n_f32(0);
+ while (sourceP < endP) {
+ float32x4_t source = vld1q_f32(sourceP);
+ fourMax = vmaxq_f32(fourMax, vabsq_f32(source));
+ sourceP += 4;
+ }
+ float32x2_t twoMax = vmax_f32(vget_low_f32(fourMax), vget_high_f32(fourMax));
+
+ float groupMax[2];
+ vst1_f32(groupMax, twoMax);
+ max = std::max(groupMax[0], groupMax[1]);
+
+ n = tailFrames;
+ }
#endif
while (n--) {
@@ -522,6 +647,22 @@ void vmaxmgv(const float* sourceP, int sourceStride, float* maxP, size_t framesT
ASSERT(maxP);
*maxP = max;
}
+
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess)
+{
+ int n = framesToProcess;
+ float lowThreshold = *lowThresholdP;
+ float highThreshold = *highThresholdP;
+
+ // FIXME: Optimize for SSE2.
+ // FIXME: Optimize for NEON.
+ while (n--) {
+ *destP = std::max(std::min(*sourceP, highThreshold), lowThreshold);
+ sourceP += sourceStride;
+ destP += destStride;
+ }
+}
+
#endif // OS(DARWIN)
} // namespace VectorMath
diff --git a/Source/WebCore/platform/audio/VectorMath.h b/Source/WebCore/platform/audio/VectorMath.h
index 702251920..863bc4be7 100644
--- a/Source/WebCore/platform/audio/VectorMath.h
+++ b/Source/WebCore/platform/audio/VectorMath.h
@@ -49,6 +49,9 @@ void vmul(const float* source1P, int sourceStride1, const float* source2P, int s
// Multiplies two complex vectors.
void zvmul(const float* real1P, const float* imag1P, const float* real2P, const float* imag2P, float* realDestP, float* imagDestP, size_t framesToProcess);
+// Copies elements while clipping values to the threshold inputs.
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess);
+
} // namespace VectorMath
} // namespace WebCore
diff --git a/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp b/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp
index 01aa371cf..541b26d9c 100644
--- a/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp
+++ b/Source/WebCore/platform/audio/gstreamer/AudioDestinationGStreamer.cpp
@@ -53,7 +53,7 @@ static void onGStreamerWavparsePadAddedCallback(GstElement* element, GstPad* pad
AudioDestinationGStreamer::AudioDestinationGStreamer(AudioIOCallback& callback, float sampleRate)
: m_callback(callback)
- , m_renderBus(2, framesToPull, true)
+ , m_renderBus(2, framesToPull, false)
, m_sampleRate(sampleRate)
, m_isPlaying(false)
{
diff --git a/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp b/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp
index c3bcbbeea..20b02b0ed 100644
--- a/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp
+++ b/Source/WebCore/platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp
@@ -49,7 +49,6 @@ struct _WebKitWebAudioSourcePrivate {
AudioBus* bus;
AudioIOCallback* provider;
guint framesToPull;
- guint64 currentBufferOffset;
GRefPtr<GstElement> interleave;
GRefPtr<GstElement> wavEncoder;
@@ -185,7 +184,6 @@ static void webkit_web_audio_src_init(WebKitWebAudioSrc* src)
priv->provider = 0;
priv->bus = 0;
- priv->currentBufferOffset = 0;
priv->mutex = g_new(GStaticRecMutex, 1);
g_static_rec_mutex_init(priv->mutex);
@@ -219,7 +217,6 @@ static void webKitWebAudioSrcConstructed(GObject* object)
gst_bin_add_many(GST_BIN(src), priv->interleave.get(), priv->wavEncoder.get(), NULL);
gst_element_link_pads_full(priv->interleave.get(), "src", priv->wavEncoder.get(), "sink", GST_PAD_LINK_CHECK_NOTHING);
-
// For each channel of the bus create a new upstream branch for interleave, like:
// queue ! capsfilter ! audioconvert. which is plugged to a new interleave request sinkpad.
for (unsigned channelIndex = 0; channelIndex < priv->bus->numberOfChannels(); channelIndex++) {
@@ -247,7 +244,6 @@ static void webKitWebAudioSrcConstructed(GObject* object)
}
priv->pads = g_slist_reverse(priv->pads);
-
// wavenc's src pad is the only visible pad of our element.
GRefPtr<GstPad> targetPad = adoptGRef(gst_element_get_static_pad(priv->wavEncoder.get(), "src"));
gst_ghost_pad_set_target(GST_GHOST_PAD(priv->sourcePad), targetPad.get());
@@ -323,32 +319,33 @@ static void webKitWebAudioSrcLoop(WebKitWebAudioSrc* src)
if (!priv->provider || !priv->bus)
return;
- // FIXME: Add support for local/live audio input.
- priv->provider->render(0, priv->bus, priv->framesToPull);
-
+ GSList* channelBufferList = 0;
unsigned bufferSize = priv->framesToPull * sizeof(float);
- for (unsigned index = 0; index < g_slist_length(priv->pads); index++) {
- GstPad* pad = static_cast<GstPad*>(g_slist_nth_data(priv->pads, index));
+ for (unsigned i = 0; i < g_slist_length(priv->pads); i++) {
+ GstBuffer* channelBuffer = gst_buffer_new_and_alloc(bufferSize);
+ ASSERT(channelBuffer);
+ channelBufferList = g_slist_prepend(channelBufferList, channelBuffer);
+ priv->bus->setChannelMemory(i, reinterpret_cast<float*>(GST_BUFFER_DATA(channelBuffer)), priv->framesToPull);
+ }
+ channelBufferList = g_slist_reverse(channelBufferList);
- GstBuffer* buffer = gst_buffer_new();
- ASSERT(buffer);
- ASSERT(!GST_BUFFER_MALLOCDATA(buffer));
+ // FIXME: Add support for local/live audio input.
+ priv->provider->render(0, priv->bus, priv->framesToPull);
- GST_BUFFER_DATA(buffer) = reinterpret_cast<guint8*>(const_cast<float*>(priv->bus->channel(index)->data()));
- GST_BUFFER_SIZE(buffer) = bufferSize;
- GST_BUFFER_OFFSET(buffer) = priv->currentBufferOffset;
- GST_BUFFER_OFFSET_END(buffer) = priv->currentBufferOffset + priv->framesToPull;
+ for (unsigned i = 0; i < g_slist_length(priv->pads); i++) {
+ GstPad* pad = static_cast<GstPad*>(g_slist_nth_data(priv->pads, i));
+ GstBuffer* channelBuffer = static_cast<GstBuffer*>(g_slist_nth_data(channelBufferList, i));
GRefPtr<GstCaps> monoCaps = adoptGRef(getGStreamerMonoAudioCaps(priv->sampleRate));
GstStructure* structure = gst_caps_get_structure(monoCaps.get(), 0);
- GstAudioChannelPosition channelPosition = webKitWebAudioGStreamerChannelPosition(index);
+ GstAudioChannelPosition channelPosition = webKitWebAudioGStreamerChannelPosition(i);
gst_audio_set_channel_positions(structure, &channelPosition);
- gst_buffer_set_caps(buffer, monoCaps.get());
+ gst_buffer_set_caps(channelBuffer, monoCaps.get());
- gst_pad_chain(pad, buffer);
+ gst_pad_chain(pad, channelBuffer);
}
- priv->currentBufferOffset += priv->framesToPull;
+ g_slist_free(channelBufferList);
}
static GstStateChangeReturn webKitWebAudioSrcChangeState(GstElement* element, GstStateChange transition)
diff --git a/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp b/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp
index 95d2eb33e..88bccf9f2 100644
--- a/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp
+++ b/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp
@@ -34,11 +34,14 @@
#include "AudioIOCallback.h"
#include "FloatConversion.h"
+#include "VectorMath.h"
#include <CoreAudio/AudioHardware.h>
namespace WebCore {
const int kBufferSize = 128;
+const float kLowThreshold = -1;
+const float kHighThreshold = 1;
// Factory method: Mac-implementation
PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, float sampleRate)
@@ -158,6 +161,12 @@ OSStatus AudioDestinationMac::render(UInt32 numberOfFrames, AudioBufferList* ioD
// FIXME: Add support for local/live audio input.
m_callback.render(0, &m_renderBus, numberOfFrames);
+ // Clamp values at 0db (i.e., [-1.0, 1.0])
+ for (unsigned i = 0; i < m_renderBus.numberOfChannels(); ++i) {
+ AudioChannel* channel = m_renderBus.channel(i);
+ VectorMath::vclip(channel->data(), 1, &kLowThreshold, &kHighThreshold, channel->mutableData(), 1, numberOfFrames);
+ }
+
return noErr;
}
diff --git a/Source/WebCore/platform/blackberry/AsyncFileSystemBlackBerry.cpp b/Source/WebCore/platform/blackberry/AsyncFileSystemBlackBerry.cpp
index 74060a66c..2ee2b6070 100644
--- a/Source/WebCore/platform/blackberry/AsyncFileSystemBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/AsyncFileSystemBlackBerry.cpp
@@ -40,8 +40,7 @@ PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create()
return adoptPtr(new AsyncFileSystemBlackBerry());
}
-// FIXME: Add FileSystemType parameter.
-void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
UNUSED_PARAM(basePath);
UNUSED_PARAM(storageIdentifier);
diff --git a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp
new file mode 100644
index 000000000..f7e8fd088
--- /dev/null
+++ b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "AuthenticationChallengeManager.h"
+
+#include "Credential.h"
+#include "KURL.h"
+#include "PageClientBlackBerry.h"
+#include "ProtectionSpace.h"
+
+#include <BlackBerryPlatformAssert.h>
+#include <BlackBerryPlatformLog.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+typedef HashMap<PageClientBlackBerry*, bool> PageVisibilityMap;
+
+struct ChallengeInfo {
+ ChallengeInfo(const KURL&, const ProtectionSpace&, const Credential&, AuthenticationChallengeClient*, PageClientBlackBerry*);
+
+ KURL url;
+ ProtectionSpace space;
+ Credential credential;
+ AuthenticationChallengeClient* authClient;
+ PageClientBlackBerry* pageClient;
+ bool blocked;
+};
+
+ChallengeInfo::ChallengeInfo(const KURL& aUrl, const ProtectionSpace& aSpace, const Credential& aCredential,
+ AuthenticationChallengeClient* anAuthClient, PageClientBlackBerry* aPageClient)
+ : url(aUrl)
+ , space(aSpace)
+ , credential(aCredential)
+ , authClient(anAuthClient)
+ , pageClient(aPageClient)
+ , blocked(false)
+{
+}
+
+class AuthenticationChallengeManagerPrivate {
+public:
+ AuthenticationChallengeManagerPrivate();
+
+ bool resumeAuthenticationChallenge(PageClientBlackBerry*);
+ void startAuthenticationChallenge(ChallengeInfo*);
+ bool pageExists(PageClientBlackBerry*);
+
+ ChallengeInfo* m_activeChallenge;
+ PageVisibilityMap m_pageVisibilityMap;
+ Vector<OwnPtr<ChallengeInfo> > m_challenges;
+};
+
+AuthenticationChallengeManagerPrivate::AuthenticationChallengeManagerPrivate()
+ : m_activeChallenge(0)
+{
+}
+
+bool AuthenticationChallengeManagerPrivate::resumeAuthenticationChallenge(PageClientBlackBerry* client)
+{
+ ASSERT(!m_activeChallenge);
+
+ for (size_t i = 0; i < m_challenges.size(); ++i) {
+ if (m_challenges[i]->pageClient == client && m_challenges[i]->blocked) {
+ startAuthenticationChallenge(m_challenges[i].get());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void AuthenticationChallengeManagerPrivate::startAuthenticationChallenge(ChallengeInfo* info)
+{
+ m_activeChallenge = info;
+ m_activeChallenge->blocked = false;
+ m_activeChallenge->pageClient->authenticationChallenge(m_activeChallenge->url, m_activeChallenge->space, m_activeChallenge->credential);
+}
+
+bool AuthenticationChallengeManagerPrivate::pageExists(PageClientBlackBerry* client)
+{
+ return m_pageVisibilityMap.find(client) != m_pageVisibilityMap.end();
+}
+
+AuthenticationChallengeManager::AuthenticationChallengeManager()
+ : d(adoptPtr(new AuthenticationChallengeManagerPrivate))
+{
+}
+
+void AuthenticationChallengeManager::pageCreated(PageClientBlackBerry* client)
+{
+ d->m_pageVisibilityMap.add(client, true);
+}
+
+void AuthenticationChallengeManager::pageDeleted(PageClientBlackBerry* client)
+{
+ d->m_pageVisibilityMap.remove(client);
+
+ if (d->m_activeChallenge && d->m_activeChallenge->pageClient == client)
+ d->m_activeChallenge = 0;
+
+ Vector<OwnPtr<ChallengeInfo> > existing;
+ d->m_challenges.swap(existing);
+
+ for (size_t i = 0; i < existing.size(); ++i) {
+ if (existing[i]->pageClient != client)
+ d->m_challenges.append(existing[i].release());
+ }
+}
+
+void AuthenticationChallengeManager::pageVisibilityChanged(PageClientBlackBerry* client, bool visible)
+{
+ PageVisibilityMap::iterator iter = d->m_pageVisibilityMap.find(client);
+
+ ASSERT(iter != d->m_pageVisibilityMap.end());
+ if (iter == d->m_pageVisibilityMap.end()) {
+ d->m_pageVisibilityMap.add(client, visible);
+ return;
+ }
+
+ if (iter->second == visible)
+ return;
+
+ iter->second = visible;
+ if (!visible)
+ return;
+
+ if (d->m_activeChallenge)
+ return;
+
+ d->resumeAuthenticationChallenge(client);
+}
+
+void AuthenticationChallengeManager::authenticationChallenge(const KURL& url, const ProtectionSpace& space,
+ const Credential& credential, AuthenticationChallengeClient* authClient, PageClientBlackBerry* pageClient)
+{
+ BLACKBERRY_ASSERT(authClient);
+ BLACKBERRY_ASSERT(pageClient);
+
+ ChallengeInfo* info = new ChallengeInfo(url, space, credential, authClient, pageClient);
+ d->m_challenges.append(adoptPtr(info));
+
+ if (d->m_activeChallenge || !pageClient->isVisible()) {
+ info->blocked = true;
+ return;
+ }
+
+ d->startAuthenticationChallenge(info);
+}
+
+void AuthenticationChallengeManager::cancelAuthenticationChallenge(AuthenticationChallengeClient* client)
+{
+ BLACKBERRY_ASSERT(client);
+
+ if (d->m_activeChallenge && d->m_activeChallenge->authClient == client)
+ d->m_activeChallenge = 0;
+
+ Vector<OwnPtr<ChallengeInfo> > existing;
+ d->m_challenges.swap(existing);
+
+ ChallengeInfo* next = 0;
+ PageClientBlackBerry* page = 0;
+
+ for (size_t i = 0; i < existing.size(); ++i) {
+ if (existing[i]->authClient != client) {
+ if (page && !next && existing[i]->pageClient == page)
+ next = existing[i].get();
+ d->m_challenges.append(existing[i].release());
+ } else if (d->m_activeChallenge == existing[i].get())
+ page = existing[i]->pageClient;
+ }
+
+ if (next)
+ d->startAuthenticationChallenge(next);
+}
+
+void AuthenticationChallengeManager::notifyChallengeResult(const KURL& url, const ProtectionSpace& space,
+ AuthenticationChallengeResult result, const Credential& credential)
+{
+ d->m_activeChallenge = 0;
+
+ Vector<OwnPtr<ChallengeInfo> > existing;
+ d->m_challenges.swap(existing);
+
+ ChallengeInfo* next = 0;
+ PageClientBlackBerry* page = 0;
+
+ for (size_t i = 0; i < existing.size(); ++i) {
+ if (existing[i]->space != space) {
+ if (page && !next && existing[i]->pageClient == page)
+ next = existing[i].get();
+ d->m_challenges.append(existing[i].release());
+ } else {
+ page = existing[i]->pageClient;
+ existing[i]->authClient->notifyChallengeResult(existing[i]->url, space, result, credential);
+
+ // After calling notifyChallengeResult(), page could be destroyed or something.
+ if (!d->pageExists(page) || !page->isVisible())
+ page = 0;
+ }
+ }
+
+ if (next)
+ d->startAuthenticationChallenge(next);
+}
+
+// Keep following code at the end of this file!!!
+static AuthenticationChallengeManager* s_manager = 0;
+
+AuthenticationChallengeManager* AuthenticationChallengeManager::instance()
+{
+ ASSERT(s_manager);
+ return s_manager;
+}
+
+void AuthenticationChallengeManager::init()
+{
+ ASSERT(!s_manager);
+ s_manager = new AuthenticationChallengeManager();
+}
+
+// No more code after this line, all new code should come before s_manager declaration!!!
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
index 52224f511..a5d51e272 100644
--- a/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
+++ b/Source/WebCore/platform/blackberry/AuthenticationChallengeManager.h
@@ -19,8 +19,13 @@
#ifndef AuthenticationChallengeManager_h
#define AuthenticationChallengeManager_h
+#include <wtf/OwnPtr.h>
+
+class PageClientBlackBerry;
+
namespace WebCore {
+class AuthenticationChallengeManagerPrivate;
class Credential;
class KURL;
class ProtectionSpace;
@@ -35,6 +40,27 @@ public:
virtual void notifyChallengeResult(const KURL&, const ProtectionSpace&, AuthenticationChallengeResult, const Credential&) = 0;
};
+class AuthenticationChallengeManager {
+public:
+ static void init();
+ static AuthenticationChallengeManager* instance();
+
+ void pageCreated(PageClientBlackBerry*);
+ void pageDeleted(PageClientBlackBerry*);
+ void pageVisibilityChanged(PageClientBlackBerry*, bool visible);
+
+ void authenticationChallenge(const KURL&, const ProtectionSpace&, const Credential&, AuthenticationChallengeClient*, PageClientBlackBerry*);
+ void cancelAuthenticationChallenge(AuthenticationChallengeClient*);
+ void notifyChallengeResult(const KURL&, const ProtectionSpace&, AuthenticationChallengeResult, const Credential&);
+
+private:
+ AuthenticationChallengeManager();
+ ~AuthenticationChallengeManager();
+
+ OwnPtr<AuthenticationChallengeManagerPrivate> d;
+};
+
+
} // namespace WebCore
#endif // AuthenticationChallengeManager_h
diff --git a/Source/WebCore/platform/blackberry/ClipboardBlackBerry.cpp b/Source/WebCore/platform/blackberry/ClipboardBlackBerry.cpp
index 2a31be862..ade22ef47 100644
--- a/Source/WebCore/platform/blackberry/ClipboardBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/ClipboardBlackBerry.cpp
@@ -78,13 +78,13 @@ bool ClipboardBlackBerry::setData(const String& type, const String& text)
return true;
}
-HashSet<String> ClipboardBlackBerry::types() const
+ListHashSet<String> ClipboardBlackBerry::types() const
{
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
- return HashSet<String>();
+ return ListHashSet<String>();
// We use hardcoded list here since there seems to be no API to get the list.
- HashSet<String> ret;
+ ListHashSet<String> ret;
ret.add("text/plain");
ret.add("text/html");
ret.add("text/url");
diff --git a/Source/WebCore/platform/blackberry/ClipboardBlackBerry.h b/Source/WebCore/platform/blackberry/ClipboardBlackBerry.h
index 17effce0f..37da514b0 100644
--- a/Source/WebCore/platform/blackberry/ClipboardBlackBerry.h
+++ b/Source/WebCore/platform/blackberry/ClipboardBlackBerry.h
@@ -39,7 +39,7 @@ public:
bool setData(const String& type, const String& data);
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
virtual DragImageRef createDragImage(IntPoint&) const;
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
diff --git a/Source/WebCore/platform/blackberry/CookieManager.cpp b/Source/WebCore/platform/blackberry/CookieManager.cpp
index db012bfb4..f2554941b 100644
--- a/Source/WebCore/platform/blackberry/CookieManager.cpp
+++ b/Source/WebCore/platform/blackberry/CookieManager.cpp
@@ -179,7 +179,7 @@ String CookieManager::generateHtmlFragmentForCookies()
Vector<ParsedCookie*> cookieCandidates;
for (HashMap<String, CookieMap*>::iterator it = m_managerMap.begin(); it != m_managerMap.end(); ++it)
- it->second->getAllChildCookies(&cookieCandidates);
+ it->value->getAllChildCookies(&cookieCandidates);
String result;
ParsedCookie* cookie = 0;
@@ -317,7 +317,7 @@ void CookieManager::removeAllCookies(BackingStoreRemovalPolicy backingStoreRemov
HashMap<String, CookieMap*>::iterator first = m_managerMap.begin();
HashMap<String, CookieMap*>::iterator end = m_managerMap.end();
for (HashMap<String, CookieMap*>::iterator it = first; it != end; ++it)
- it->second->deleteAllCookiesAndDomains();
+ it->value->deleteAllCookiesAndDomains();
if (backingStoreRemoval == RemoveFromBackingStore)
m_cookieBackingStore->removeAll();
diff --git a/Source/WebCore/platform/blackberry/CookieMap.cpp b/Source/WebCore/platform/blackberry/CookieMap.cpp
index bbe9a7ced..af485b54c 100644
--- a/Source/WebCore/platform/blackberry/CookieMap.cpp
+++ b/Source/WebCore/platform/blackberry/CookieMap.cpp
@@ -172,7 +172,7 @@ ParsedCookie* CookieMap::removeOldestCookie()
CookieLog("CookieMap - looking into subdomains");
for (HashMap<String, CookieMap*>::iterator it = m_subdomains.begin(); it != m_subdomains.end(); ++it) {
- oldestCookie = it->second->removeOldestCookie();
+ oldestCookie = it->value->removeOldestCookie();
if (oldestCookie)
break;
}
@@ -214,7 +214,7 @@ void CookieMap::getAllChildCookies(Vector<ParsedCookie*>* stackOfCookies)
CookieLog("CookieMap - getAllChildCookies in Map - %s", getName().utf8().data());
getAllCookies(stackOfCookies);
for (HashMap<String, CookieMap*>::iterator it = m_subdomains.begin(); it != m_subdomains.end(); ++it)
- it->second->getAllChildCookies(stackOfCookies);
+ it->value->getAllChildCookies(stackOfCookies);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp b/Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp
index 83339efd4..6d7b3a389 100644
--- a/Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/LocalizedStringsBlackBerry.cpp
@@ -21,6 +21,7 @@
#include "IntSize.h"
#include "NotImplemented.h"
+#include <BlackBerryPlatformString.h>
#include <LocaleHandler.h>
#include <LocalizeResource.h>
#include <wtf/Vector.h>
diff --git a/Source/WebCore/platform/blackberry/MIMETypeRegistryBlackBerry.cpp b/Source/WebCore/platform/blackberry/MIMETypeRegistryBlackBerry.cpp
index 44c6d8ec0..06d010d4a 100644
--- a/Source/WebCore/platform/blackberry/MIMETypeRegistryBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/MIMETypeRegistryBlackBerry.cpp
@@ -31,18 +31,19 @@
#include "NotImplemented.h"
#include <BlackBerryPlatformCommonFunctions.h>
+#include <BlackBerryPlatformString.h>
#include <wtf/text/CString.h>
namespace WebCore {
String MIMETypeRegistry::getMIMETypeForExtension(const String& extension)
{
- return String(BlackBerry::Platform::getMIMETypeForExtension(extension.lower().utf8().data()).c_str());
+ return BlackBerry::Platform::getMIMETypeForExtension(extension.lower());
}
String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type)
{
- return String(BlackBerry::Platform::getPreferredExtensionForMIMEType(type.lower().utf8().data()).c_str());
+ return BlackBerry::Platform::getPreferredExtensionForMIMEType(type.lower());
}
bool MIMETypeRegistry::isApplicationPluginMIMEType(const String&)
diff --git a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
index bdb2f1607..f2c7c0e65 100644
--- a/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
+++ b/Source/WebCore/platform/blackberry/PageClientBlackBerry.h
@@ -72,7 +72,7 @@ public:
virtual int showAlertDialog(BlackBerry::WebKit::WebPageClient::AlertType) = 0;
virtual bool isActive() const = 0;
virtual bool isVisible() const = 0;
- virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&, WebCore::AuthenticationChallengeClient*) = 0;
+ virtual void authenticationChallenge(const WebCore::KURL&, const WebCore::ProtectionSpace&, const WebCore::Credential&) = 0;
virtual SaveCredentialType notifyShouldSaveCredential(bool) = 0;
virtual void syncProxyCredential(const WebCore::Credential&) = 0;
};
diff --git a/Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp b/Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp
index 24d200774..c82afad48 100644
--- a/Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/PasteboardBlackBerry.cpp
@@ -63,9 +63,9 @@ void Pasteboard::writeClipboard(Clipboard*)
void Pasteboard::writeSelection(Range* selectedRange, bool, Frame* frame)
{
- std::string text = frame->editor()->selectedText().utf8().data();
- std::string html = createMarkup(selectedRange, 0, AnnotateForInterchange).utf8().data();
- std::string url = frame->document()->url().string().utf8().data();
+ WTF::String text = frame->editor()->selectedText();
+ WTF::String html = createMarkup(selectedRange, 0, AnnotateForInterchange);
+ WTF::String url = frame->document()->url().string();
BlackBerry::Platform::Clipboard::write(text, html, url);
}
@@ -73,17 +73,17 @@ void Pasteboard::writeSelection(Range* selectedRange, bool, Frame* frame)
void Pasteboard::writeURL(KURL const& url, String const&, Frame*)
{
ASSERT(!url.isEmpty());
- BlackBerry::Platform::Clipboard::writeURL(url.string().utf8().data());
+ BlackBerry::Platform::Clipboard::writeURL(url.string());
}
void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
{
- BlackBerry::Platform::Clipboard::writePlainText(text.utf8().data());
+ BlackBerry::Platform::Clipboard::writePlainText(text);
}
String Pasteboard::plainText(Frame*)
{
- return String::fromUTF8(BlackBerry::Platform::Clipboard::readPlainText().c_str());
+ return BlackBerry::Platform::Clipboard::readPlainText();
}
PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText)
@@ -93,10 +93,10 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
// Note: We are able to check if the format exists prior to reading but the check & the early return
// path of get_clipboard_data are the exact same, so just use get_clipboard_data and validate the
// return value to determine if the data was present.
- String html = String::fromUTF8(BlackBerry::Platform::Clipboard::readHTML().c_str());
+ String html = BlackBerry::Platform::Clipboard::readHTML();
RefPtr<DocumentFragment> fragment;
if (!html.isEmpty()) {
- String url = String::fromUTF8(BlackBerry::Platform::Clipboard::readURL().c_str());
+ String url = BlackBerry::Platform::Clipboard::readURL();
if (fragment = createFragmentFromMarkup(frame->document(), html, url, DisallowScriptingContent))
return fragment.release();
}
@@ -104,7 +104,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
if (!allowPlainText)
return 0;
- String text = String::fromUTF8(BlackBerry::Platform::Clipboard::readPlainText().c_str());
+ String text = BlackBerry::Platform::Clipboard::readPlainText();
if (fragment = createFragmentFromText(context.get(), text)) {
chosePlainText = true;
return fragment.release();
diff --git a/Source/WebCore/platform/blackberry/PlatformKeyboardEventBlackBerry.cpp b/Source/WebCore/platform/blackberry/PlatformKeyboardEventBlackBerry.cpp
index 4914305ba..8dc2e0243 100644
--- a/Source/WebCore/platform/blackberry/PlatformKeyboardEventBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/PlatformKeyboardEventBlackBerry.cpp
@@ -452,7 +452,7 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(const BlackBerry::Platform::Keyboar
if (event.character() == KEYCODE_BACK_TAB)
m_modifiers |= ShiftKey; // BackTab should be treated as Shift + Tab.
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "Keyboard event received text=%lc, keyIdentifier=%s, windowsVirtualKeyCode=%d", event.character(), m_keyIdentifier.latin1().data(), m_windowsVirtualKeyCode);
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "Keyboard event received text=%lc, keyIdentifier=%s, windowsVirtualKeyCode=%d", event.character(), m_keyIdentifier.latin1().data(), m_windowsVirtualKeyCode);
}
bool PlatformKeyboardEvent::currentCapsLockState()
diff --git a/Source/WebCore/platform/blackberry/ReadOnlyLatin1String.h b/Source/WebCore/platform/blackberry/ReadOnlyLatin1String.h
deleted file mode 100644
index 613dbda86..000000000
--- a/Source/WebCore/platform/blackberry/ReadOnlyLatin1String.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef ReadOnlyLatin1String_h
-#define ReadOnlyLatin1String_h
-
-#include <wtf/text/CString.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class ReadOnlyLatin1String {
-public:
- explicit ReadOnlyLatin1String(const String& string)
- {
- if (string.is8Bit())
- m_string = string;
- else {
- ASSERT(string.containsOnlyLatin1());
- m_cstring = string.latin1();
- }
- }
-
- const char* data() const { return m_string.isNull() ? m_cstring.data() : reinterpret_cast<const char*>(m_string.characters8()); }
-
- size_t length() const { return m_string.isNull() ? m_cstring.length() : m_string.length(); }
-
-private:
- String m_string;
- CString m_cstring;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp b/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp
index a9c09a119..b7019ff1d 100644
--- a/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp
+++ b/Source/WebCore/platform/blackberry/RenderThemeBlackBerry.cpp
@@ -314,14 +314,13 @@ void RenderThemeBlackBerry::adjustSearchFieldStyle(StyleResolver*, RenderStyle*
void RenderThemeBlackBerry::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
{
- static const float defaultControlFontPixelSize = 13;
- static const float defaultCancelButtonSize = 9;
+ static const float defaultControlFontPixelSize = 10;
+ static const float defaultCancelButtonSize = 13;
static const float minCancelButtonSize = 5;
- static const float maxCancelButtonSize = 21;
// Scale the button size based on the font size
float fontScale = style->fontSize() / defaultControlFontPixelSize;
- int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
+ int cancelButtonSize = lroundf(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale));
Length length(cancelButtonSize, Fixed);
style->setWidth(length);
style->setHeight(length);
diff --git a/Source/WebCore/platform/cf/BinaryPropertyList.cpp b/Source/WebCore/platform/cf/BinaryPropertyList.cpp
index bec2ec950..b27d7d7cd 100644
--- a/Source/WebCore/platform/cf/BinaryPropertyList.cpp
+++ b/Source/WebCore/platform/cf/BinaryPropertyList.cpp
@@ -229,7 +229,7 @@ void BinaryPropertyListPlan::writeIntegerArray(const int* integers, size_t size)
return;
for (size_t i = 0; i < size; ++i)
writeInteger(integers[i]);
- addResult.iterator->second = m_currentObjectReference++;
+ addResult.iterator->value = m_currentObjectReference++;
writeArrayObject(size);
m_currentAggregateSize = savedAggregateSize;
}
diff --git a/Source/WebCore/platform/cf/RunLoopTimerCF.cpp b/Source/WebCore/platform/cf/RunLoopTimerCF.cpp
index f62299ed6..6b8cce520 100644
--- a/Source/WebCore/platform/cf/RunLoopTimerCF.cpp
+++ b/Source/WebCore/platform/cf/RunLoopTimerCF.cpp
@@ -31,6 +31,7 @@
#if PLATFORM(MAC) && HAVE(RUNLOOP_TIMER)
#include "RunLoopTimer.h"
+#include "AutodrainedPool.h"
namespace WebCore {
@@ -41,6 +42,11 @@ RunLoopTimerBase::~RunLoopTimerBase()
static void timerFired(CFRunLoopTimerRef, void* context)
{
+ // CFRunLoopTimer does not create an NSAutoreleasePool, like NSTimer does. This can lead to
+ // autoreleased objects being pushed into NSAutoreleasePools underneath the run loop, which
+ // are very infrequently drained. Create a new autorelease pool here to give autoreleased objects
+ // a place to collect.
+ AutodrainedPool pool;
RunLoopTimerBase* timer = static_cast<RunLoopTimerBase*>(context);
timer->fired();
}
diff --git a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp
index ec7eebe63..9b11f23fe 100644
--- a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp
+++ b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp
@@ -48,10 +48,10 @@ PassRefPtr<ChromiumDataObject> ChromiumDataObject::createFromPasteboard()
uint64_t sequenceNumber = WebKit::Platform::current()->clipboard()->sequenceNumber(currentPasteboardBuffer());
bool ignored;
WebKit::WebVector<WebKit::WebString> webTypes = WebKit::Platform::current()->clipboard()->readAvailableTypes(currentPasteboardBuffer(), &ignored);
- HashSet<String> types;
+ ListHashSet<String> types;
for (size_t i = 0; i < webTypes.size(); ++i)
types.add(webTypes[i]);
- for (HashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it)
+ for (ListHashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it)
dataObject->m_itemList.append(ChromiumDataObjectItem::createFromPasteboard(*it, sequenceNumber));
return dataObject.release();
}
@@ -126,9 +126,9 @@ void ChromiumDataObject::clearAllExceptFiles()
}
}
-HashSet<String> ChromiumDataObject::types() const
+ListHashSet<String> ChromiumDataObject::types() const
{
- HashSet<String> results;
+ ListHashSet<String> results;
bool containsFiles = false;
for (size_t i = 0; i < m_itemList.size(); ++i) {
if (m_itemList[i]->kind() == DataTransferItem::kindString)
diff --git a/Source/WebCore/platform/chromium/ChromiumDataObject.h b/Source/WebCore/platform/chromium/ChromiumDataObject.h
index 4a5e4fed4..2551c45da 100644
--- a/Source/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/Source/WebCore/platform/chromium/ChromiumDataObject.h
@@ -33,7 +33,7 @@
#include "ChromiumDataObjectItem.h"
#include "Supplementable.h"
-#include <wtf/HashSet.h>
+#include <wtf/ListHashSet.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>
@@ -69,7 +69,7 @@ public:
void clearData(const String& type);
void clearAllExceptFiles();
- HashSet<String> types() const;
+ ListHashSet<String> types() const;
String getData(const String& type) const;
bool setData(const String& type, const String& data);
diff --git a/Source/WebCore/platform/chromium/ClipboardChromium.cpp b/Source/WebCore/platform/chromium/ClipboardChromium.cpp
index b065237b9..f58ebcef9 100644
--- a/Source/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/Source/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -45,7 +45,6 @@
#include "Image.h"
#include "MIMETypeRegistry.h"
#include "NamedNodeMap.h"
-#include "PlatformSupport.h"
#include "Range.h"
#include "RenderImage.h"
#include "StringCallback.h"
@@ -227,6 +226,8 @@ ClipboardChromium::ClipboardChromium(ClipboardType clipboardType,
ClipboardChromium::~ClipboardChromium()
{
+ if (m_dragImage)
+ m_dragImage->removeClient(this);
}
PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType,
@@ -274,10 +275,10 @@ bool ClipboardChromium::setData(const String& type, const String& data)
}
// extensions beyond IE's API
-HashSet<String> ClipboardChromium::types() const
+ListHashSet<String> ClipboardChromium::types() const
{
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
- return HashSet<String>();
+ return ListHashSet<String>();
return m_dataObject->types();
}
diff --git a/Source/WebCore/platform/chromium/ClipboardChromium.h b/Source/WebCore/platform/chromium/ClipboardChromium.h
index a5cbf53eb..e41838da9 100644
--- a/Source/WebCore/platform/chromium/ClipboardChromium.h
+++ b/Source/WebCore/platform/chromium/ClipboardChromium.h
@@ -84,7 +84,7 @@ namespace WebCore {
bool platformClipboardChanged() const;
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
void setDragImage(CachedImage*, const IntPoint&);
diff --git a/Source/WebCore/platform/chromium/LanguageChromium.cpp b/Source/WebCore/platform/chromium/LanguageChromium.cpp
index 46cc8add6..4544e42a1 100644
--- a/Source/WebCore/platform/chromium/LanguageChromium.cpp
+++ b/Source/WebCore/platform/chromium/LanguageChromium.cpp
@@ -40,8 +40,10 @@ namespace WebCore {
static String platformLanguage()
{
DEFINE_STATIC_LOCAL(String, computedDefaultLanguage, ());
- if (computedDefaultLanguage.isEmpty())
+ if (computedDefaultLanguage.isEmpty()) {
computedDefaultLanguage.append(WebKit::Platform::current()->defaultLocale());
+ ASSERT(!computedDefaultLanguage.isEmpty());
+ }
return computedDefaultLanguage;
}
diff --git a/Source/WebCore/platform/chromium/PlatformSupport.h b/Source/WebCore/platform/chromium/PlatformSupport.h
index 7af75b8ef..4fc3d63c4 100644
--- a/Source/WebCore/platform/chromium/PlatformSupport.h
+++ b/Source/WebCore/platform/chromium/PlatformSupport.h
@@ -127,136 +127,6 @@ public:
GraphicsContext*, int part, int state, int classicState, const IntRect&);
static void paintProgressBar(
GraphicsContext*, const IntRect& barRect, const IntRect& valueRect, bool determinate, double animatedSeconds);
-#elif OS(DARWIN)
- enum ThemePaintState {
- StateDisabled,
- StateInactive,
- StateActive,
- StatePressed,
- };
-
- enum ThemePaintSize {
- SizeRegular,
- SizeSmall,
- };
-
- enum ThemePaintScrollbarOrientation {
- ScrollbarOrientationHorizontal,
- ScrollbarOrientationVertical,
- };
-
- enum ThemePaintScrollbarParent {
- ScrollbarParentScrollView,
- ScrollbarParentRenderLayer,
- };
-
- struct ThemePaintScrollbarInfo {
- ThemePaintScrollbarOrientation orientation;
- ThemePaintScrollbarParent parent;
- int maxValue;
- int currentValue;
- int visibleSize;
- int totalSize;
- };
-
- static void paintScrollbarThumb(GraphicsContext*, ThemePaintState, ThemePaintSize, const IntRect&, const ThemePaintScrollbarInfo&);
-#elif OS(UNIX)
- // The UI part which is being accessed.
- enum ThemePart {
- // ScrollbarTheme parts
- PartScrollbarDownArrow,
- PartScrollbarLeftArrow,
- PartScrollbarRightArrow,
- PartScrollbarUpArrow,
- PartScrollbarHorizontalThumb,
- PartScrollbarVerticalThumb,
- PartScrollbarHorizontalTrack,
- PartScrollbarVerticalTrack,
-
- // RenderTheme parts
- PartCheckbox,
- PartRadio,
- PartButton,
- PartTextField,
- PartMenuList,
- PartSliderTrack,
- PartSliderThumb,
- PartInnerSpinButton,
- PartProgressBar
- };
-
- // The current state of the associated Part.
- enum ThemePaintState {
- StateDisabled,
- StateHover,
- StateNormal,
- StatePressed
- };
-
- struct ScrollbarTrackExtraParams {
- // The bounds of the entire track, as opposed to the part being painted.
- int trackX;
- int trackY;
- int trackWidth;
- int trackHeight;
- };
-
- struct ButtonExtraParams {
- bool checked;
- bool indeterminate; // Whether the button state is indeterminate.
- bool isDefault; // Whether the button is default button.
- bool hasBorder;
- unsigned backgroundColor;
- };
-
- struct TextFieldExtraParams {
- bool isTextArea;
- bool isListbox;
- unsigned backgroundColor;
- };
-
- struct MenuListExtraParams {
- bool hasBorder;
- bool hasBorderRadius;
- int arrowX;
- int arrowY;
- unsigned backgroundColor;
- };
-
- struct SliderExtraParams {
- bool vertical;
- bool inDrag;
- };
-
- struct InnerSpinButtonExtraParams {
- bool spinUp;
- bool readOnly;
- };
-
- struct ProgressBarExtraParams {
- bool determinate;
- int valueRectX;
- int valueRectY;
- int valueRectWidth;
- int valueRectHeight;
- };
-
- union ThemePaintExtraParams {
- ScrollbarTrackExtraParams scrollbarTrack;
- ButtonExtraParams button;
- TextFieldExtraParams textField;
- MenuListExtraParams menuList;
- SliderExtraParams slider;
- InnerSpinButtonExtraParams innerSpin;
- ProgressBarExtraParams progressBar;
- };
-
- // Gets the size of the given theme part. For variable sized items
- // like vertical scrollbar thumbs, the width will be the required width of
- // the track while the height will be the minimum height.
- static IntSize getThemePartSize(ThemePart);
- // Paint the given the given theme part.
- static void paintThemePart(GraphicsContext*, ThemePart, ThemePaintState, const IntRect&, const ThemePaintExtraParams*);
#endif
};
diff --git a/Source/WebCore/platform/chromium/PopupListBox.cpp b/Source/WebCore/platform/chromium/PopupListBox.cpp
index b8aad6b2c..5c76ae101 100644
--- a/Source/WebCore/platform/chromium/PopupListBox.cpp
+++ b/Source/WebCore/platform/chromium/PopupListBox.cpp
@@ -614,12 +614,16 @@ void PopupListBox::setOriginalIndex(int index)
int PopupListBox::getRowHeight(int index)
{
+ int minimumHeight = PopupMenuChromium::minimumRowHeight();
+ if (m_settings.deviceSupportsTouch)
+ minimumHeight = max(minimumHeight, PopupMenuChromium::optionRowHeightForTouch());
+
if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone())
- return PopupMenuChromium::minimumRowHeight();
+ return minimumHeight;
// Separator row height is the same size as itself.
if (m_popupClient->itemIsSeparator(index))
- return max(separatorHeight, (PopupMenuChromium::minimumRowHeight()));
+ return max(separatorHeight, minimumHeight);
String icon = m_popupClient->itemIcon(index);
RefPtr<Image> image(Image::loadPlatformResource(icon.utf8().data()));
@@ -629,7 +633,7 @@ int PopupListBox::getRowHeight(int index)
int linePaddingHeight = m_popupClient->menuStyle().menuType() == PopupMenuStyle::AutofillPopup ? kLinePaddingHeight : 0;
int calculatedRowHeight = max(fontHeight, iconHeight) + linePaddingHeight * 2;
- return max(calculatedRowHeight, PopupMenuChromium::minimumRowHeight());
+ return max(calculatedRowHeight, minimumHeight);
}
IntRect PopupListBox::getRowBounds(int index)
diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
index 519e7cad1..0e48ffd0f 100644
--- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -40,7 +40,8 @@
namespace WebCore {
-int PopupMenuChromium::s_minimumRowHeight = 28;
+int PopupMenuChromium::s_minimumRowHeight = 0;
+int PopupMenuChromium::s_optionRowHeightForTouch = 28;
// The settings used for the drop down menu.
// This is the delegate used if none is provided.
diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.h b/Source/WebCore/platform/chromium/PopupMenuChromium.h
index 20be6e153..7d9023fba 100644
--- a/Source/WebCore/platform/chromium/PopupMenuChromium.h
+++ b/Source/WebCore/platform/chromium/PopupMenuChromium.h
@@ -56,6 +56,8 @@ public:
static int minimumRowHeight() { return s_minimumRowHeight; }
static void setMinimumRowHeight(int minimumRowHeight) { s_minimumRowHeight = minimumRowHeight; }
+ static int optionRowHeightForTouch() { return s_optionRowHeightForTouch; }
+ static void setOptionRowHeightForTouch(int optionRowHeightForTouch) { s_optionRowHeightForTouch = optionRowHeightForTouch; }
private:
PopupMenuClient* client() const { return m_popupClient; }
@@ -64,6 +66,7 @@ private:
PopupMenuPrivate p;
static int s_minimumRowHeight;
+ static int s_optionRowHeightForTouch;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
index 6f555fbd1..2e1fecc1a 100644
--- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
+++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumAndroid.cpp
@@ -28,7 +28,6 @@
#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
-#include "PlatformSupport.h"
#include "Scrollbar.h"
#include "TransformationMatrix.h"
diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
index 6b4dafc37..c88a409e5 100644
--- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
+++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
@@ -31,9 +31,12 @@
#include "config.h"
#include "ScrollbarThemeChromiumLinux.h"
-#include "PlatformSupport.h"
+#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
#include "Scrollbar.h"
+#include <public/Platform.h>
+#include <public/WebRect.h>
+#include <public/linux/WebThemeEngine.h>
namespace WebCore {
@@ -46,78 +49,70 @@ ScrollbarTheme* ScrollbarTheme::nativeTheme()
int ScrollbarThemeChromiumLinux::scrollbarThickness(ScrollbarControlSize controlSize)
{
// Horiz and Vert scrollbars are the same thickness.
- IntSize scrollbarSize = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarVerticalTrack);
+ IntSize scrollbarSize = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarVerticalTrack);
return scrollbarSize.width();
}
void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
- PlatformSupport::ThemePaintState state = scrollbar->hoveredPart() == partType ? PlatformSupport::StateHover : PlatformSupport::StateNormal;
+ WebKit::WebThemeEngine::State state = scrollbar->hoveredPart() == partType ? WebKit::WebThemeEngine::StateHover : WebKit::WebThemeEngine::StateNormal;
IntRect alignRect = trackRect(scrollbar, false);
- PlatformSupport::ThemePaintExtraParams extraParams;
+ WebKit::WebThemeEngine::ExtraParams extraParams;
+ WebKit::WebCanvas* canvas = gc->platformContext()->canvas();
extraParams.scrollbarTrack.trackX = alignRect.x();
extraParams.scrollbarTrack.trackY = alignRect.y();
extraParams.scrollbarTrack.trackWidth = alignRect.width();
extraParams.scrollbarTrack.trackHeight = alignRect.height();
- PlatformSupport::paintThemePart(
- gc,
- scrollbar->orientation() == HorizontalScrollbar ? PlatformSupport::PartScrollbarHorizontalTrack : PlatformSupport::PartScrollbarVerticalTrack,
- state,
- rect,
- &extraParams);
+ WebKit::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? WebKit::WebThemeEngine::PartScrollbarHorizontalTrack : WebKit::WebThemeEngine::PartScrollbarVerticalTrack, state, WebKit::WebRect(rect), &extraParams);
}
void ScrollbarThemeChromiumLinux::paintButton(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
{
- PlatformSupport::ThemePart paintPart;
- PlatformSupport::ThemePaintState state = PlatformSupport::StateNormal;
+ WebKit::WebThemeEngine::Part paintPart;
+ WebKit::WebThemeEngine::State state = WebKit::WebThemeEngine::StateNormal;
+ WebKit::WebCanvas* canvas = gc->platformContext()->canvas();
bool checkMin = false;
bool checkMax = false;
if (scrollbar->orientation() == HorizontalScrollbar) {
if (part == BackButtonStartPart) {
- paintPart = PlatformSupport::PartScrollbarLeftArrow;
+ paintPart = WebKit::WebThemeEngine::PartScrollbarLeftArrow;
checkMin = true;
} else {
- paintPart = PlatformSupport::PartScrollbarRightArrow;
+ paintPart = WebKit::WebThemeEngine::PartScrollbarRightArrow;
checkMax = true;
}
} else {
if (part == BackButtonStartPart) {
- paintPart = PlatformSupport::PartScrollbarUpArrow;
+ paintPart = WebKit::WebThemeEngine::PartScrollbarUpArrow;
checkMin = true;
} else {
- paintPart = PlatformSupport::PartScrollbarDownArrow;
+ paintPart = WebKit::WebThemeEngine::PartScrollbarDownArrow;
checkMax = true;
}
}
if ((checkMin && (scrollbar->currentPos() <= 0))
|| (checkMax && scrollbar->currentPos() == scrollbar->maximum())) {
- state = PlatformSupport::StateDisabled;
+ state = WebKit::WebThemeEngine::StateDisabled;
} else {
if (part == scrollbar->pressedPart())
- state = PlatformSupport::StatePressed;
+ state = WebKit::WebThemeEngine::StatePressed;
else if (part == scrollbar->hoveredPart())
- state = PlatformSupport::StateHover;
+ state = WebKit::WebThemeEngine::StateHover;
}
- PlatformSupport::paintThemePart(gc, paintPart, state, rect, 0);
+ WebKit::Platform::current()->themeEngine()->paint(canvas, paintPart, state, WebKit::WebRect(rect), 0);
}
void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, ScrollbarThemeClient* scrollbar, const IntRect& rect)
{
- PlatformSupport::ThemePaintState state;
-
+ WebKit::WebThemeEngine::State state;
+ WebKit::WebCanvas* canvas = gc->platformContext()->canvas();
if (scrollbar->pressedPart() == ThumbPart)
- state = PlatformSupport::StatePressed;
+ state = WebKit::WebThemeEngine::StatePressed;
else if (scrollbar->hoveredPart() == ThumbPart)
- state = PlatformSupport::StateHover;
+ state = WebKit::WebThemeEngine::StateHover;
else
- state = PlatformSupport::StateNormal;
- PlatformSupport::paintThemePart(
- gc,
- scrollbar->orientation() == HorizontalScrollbar ? PlatformSupport::PartScrollbarHorizontalThumb : PlatformSupport::PartScrollbarVerticalThumb,
- state,
- rect,
- 0);
+ state = WebKit::WebThemeEngine::StateNormal;
+ WebKit::Platform::current()->themeEngine()->paint(canvas, scrollbar->orientation() == HorizontalScrollbar ? WebKit::WebThemeEngine::PartScrollbarHorizontalThumb : WebKit::WebThemeEngine::PartScrollbarVerticalThumb, state, WebKit::WebRect(rect), 0);
}
bool ScrollbarThemeChromiumLinux::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
@@ -128,23 +123,23 @@ bool ScrollbarThemeChromiumLinux::shouldCenterOnThumb(ScrollbarThemeClient*, con
IntSize ScrollbarThemeChromiumLinux::buttonSize(ScrollbarThemeClient* scrollbar)
{
if (scrollbar->orientation() == VerticalScrollbar) {
- IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarUpArrow);
+ IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarUpArrow);
return IntSize(size.width(), scrollbar->height() < 2 * size.height() ? scrollbar->height() / 2 : size.height());
}
// HorizontalScrollbar
- IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarLeftArrow);
+ IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarLeftArrow);
return IntSize(scrollbar->width() < 2 * size.width() ? scrollbar->width() / 2 : size.width(), size.height());
}
int ScrollbarThemeChromiumLinux::minimumThumbLength(ScrollbarThemeClient* scrollbar)
{
if (scrollbar->orientation() == VerticalScrollbar) {
- IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarVerticalThumb);
+ IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarVerticalThumb);
return size.height();
}
- IntSize size = PlatformSupport::getThemePartSize(PlatformSupport::PartScrollbarHorizontalThumb);
+ IntSize size = WebKit::Platform::current()->themeEngine()->getSize(WebKit::WebThemeEngine::PartScrollbarHorizontalThumb);
return size.width();
}
diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
index 9fe8a900e..44ee6737c 100644
--- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
+++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm
@@ -33,11 +33,13 @@
#include "LocalCurrentGraphicsContext.h"
#include "NSScrollerImpDetails.h"
#include "PlatformContextSkia.h"
-#include "PlatformSupport.h"
#include "ScrollAnimatorMac.h"
#include "ScrollView.h"
#include "skia/ext/skia_utils_mac.h"
#include <Carbon/Carbon.h>
+#include <public/Platform.h>
+#include <public/WebRect.h>
+#include <public/mac/WebThemeEngine.h>
namespace WebCore {
@@ -58,16 +60,16 @@ ScrollbarThemeChromiumMac::~ScrollbarThemeChromiumMac()
{
}
-static PlatformSupport::ThemePaintState scrollbarStateToThemeState(ScrollbarThemeClient* scrollbar)
+static WebKit::WebThemeEngine::State scrollbarStateToThemeState(ScrollbarThemeClient* scrollbar)
{
if (!scrollbar->enabled())
- return PlatformSupport::StateDisabled;
+ return WebKit::WebThemeEngine::StateDisabled;
if (!scrollbar->isScrollableAreaActive())
- return PlatformSupport::StateInactive;
+ return WebKit::WebThemeEngine::StateInactive;
if (scrollbar->pressedPart() == ThumbPart)
- return PlatformSupport::StatePressed;
+ return WebKit::WebThemeEngine::StatePressed;
- return PlatformSupport::StateActive;
+ return WebKit::WebThemeEngine::StateActive;
}
static void scrollbarPainterPaintTrack(ScrollbarPainter scrollbarPainter, bool enabled, double value, CGFloat proportion, CGRect frameRect)
@@ -88,7 +90,7 @@ static void scrollbarPainterPaintTrack(ScrollbarPainter scrollbarPainter, bool e
}
// Override ScrollbarThemeMac::paint() to add support for the following:
-// - drawing using PlatformSupport functions
+// - drawing using WebThemeEngine functions
// - drawing tickmarks
// - Skia specific changes
bool ScrollbarThemeChromiumMac::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* context, const IntRect& damageRect)
@@ -235,19 +237,20 @@ bool ScrollbarThemeChromiumMac::paint(ScrollbarThemeClient* scrollbar, GraphicsC
paintGivenTickmarks(drawingContext, scrollbar, tickmarkTrackRect, tickmarks);
if (hasThumb(scrollbar)) {
- PlatformSupport::ThemePaintScrollbarInfo scrollbarInfo;
- scrollbarInfo.orientation = scrollbar->orientation() == HorizontalScrollbar ? PlatformSupport::ScrollbarOrientationHorizontal : PlatformSupport::ScrollbarOrientationVertical;
- scrollbarInfo.parent = scrollbar->isScrollViewScrollbar() ? PlatformSupport::ScrollbarParentScrollView : PlatformSupport::ScrollbarParentRenderLayer;
+ WebKit::WebThemeEngine::ScrollbarInfo scrollbarInfo;
+ scrollbarInfo.orientation = scrollbar->orientation() == HorizontalScrollbar ? WebKit::WebThemeEngine::ScrollbarOrientationHorizontal : WebKit::WebThemeEngine::ScrollbarOrientationVertical;
+ scrollbarInfo.parent = scrollbar->isScrollViewScrollbar() ? WebKit::WebThemeEngine::ScrollbarParentScrollView : WebKit::WebThemeEngine::ScrollbarParentRenderLayer;
scrollbarInfo.maxValue = scrollbar->maximum();
scrollbarInfo.currentValue = scrollbar->currentPos();
scrollbarInfo.visibleSize = scrollbar->visibleSize();
scrollbarInfo.totalSize = scrollbar->totalSize();
- PlatformSupport::paintScrollbarThumb(
- drawingContext,
+ WebKit::WebCanvas* webCanvas = drawingContext->platformContext()->canvas();
+ WebKit::Platform::current()->themeEngine()->paintScrollbarThumb(
+ webCanvas,
scrollbarStateToThemeState(scrollbar),
- scrollbar->controlSize() == RegularScrollbar ? PlatformSupport::SizeRegular : PlatformSupport::SizeSmall,
- scrollbar->frameRect(),
+ scrollbar->controlSize() == RegularScrollbar ? WebKit::WebThemeEngine::SizeRegular : WebKit::WebThemeEngine::SizeSmall,
+ WebKit::WebRect(scrollbar->frameRect()),
scrollbarInfo);
}
diff --git a/Source/WebCore/platform/chromium/support/WebAudioBus.cpp b/Source/WebCore/platform/chromium/support/WebAudioBus.cpp
index b373e0982..9fa85f836 100644
--- a/Source/WebCore/platform/chromium/support/WebAudioBus.cpp
+++ b/Source/WebCore/platform/chromium/support/WebAudioBus.cpp
@@ -58,6 +58,19 @@ void WebAudioBus::initialize(unsigned numberOfChannels, size_t length, double sa
#endif
}
+void WebAudioBus::resizeSmaller(size_t newLength)
+{
+#if ENABLE(WEB_AUDIO)
+ ASSERT(m_private);
+ if (m_private) {
+ ASSERT(newLength <= length());
+ m_private->resizeSmaller(newLength);
+ }
+#else
+ ASSERT_NOT_REACHED();
+#endif
+}
+
void WebAudioBus::reset()
{
#if ENABLE(WEB_AUDIO)
diff --git a/Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp b/Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp
index 33eace1d2..5cd726011 100644
--- a/Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp
+++ b/Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp
@@ -106,7 +106,7 @@ static void addHeader(HTTPHeaderMap* map, const WebString& name, const WebString
HTTPHeaderMap::AddResult result = map->add(name, value);
// It is important that values are separated by '\n', not comma, otherwise Set-Cookie header is not parseable.
if (!result.isNewEntry)
- result.iterator->second.append("\n" + String(value));
+ result.iterator->value.append("\n" + String(value));
}
void WebHTTPLoadInfo::addRequestHeader(const WebString& name, const WebString& value)
diff --git a/Source/WebCore/platform/chromium/support/WebMediaConstraints.cpp b/Source/WebCore/platform/chromium/support/WebMediaConstraints.cpp
index 05fa3f666..6b2305efe 100644
--- a/Source/WebCore/platform/chromium/support/WebMediaConstraints.cpp
+++ b/Source/WebCore/platform/chromium/support/WebMediaConstraints.cpp
@@ -40,11 +40,22 @@ using namespace WebCore;
namespace WebKit {
+WebMediaConstraint::WebMediaConstraint(const WebCore::MediaConstraint& other)
+ : m_name(other.m_name)
+ , m_value(other.m_value)
+{
+}
+
WebMediaConstraints::WebMediaConstraints(const PassRefPtr<MediaConstraints>& constraints)
: m_private(constraints)
{
}
+WebMediaConstraints::WebMediaConstraints(MediaConstraints* constraints)
+ : m_private(constraints)
+{
+}
+
void WebMediaConstraints::assign(const WebMediaConstraints& other)
{
m_private = other.m_private;
@@ -55,27 +66,22 @@ void WebMediaConstraints::reset()
m_private.reset();
}
-bool WebMediaConstraints::isNull() const
-{
- return m_private.isNull();
-}
-
-void WebMediaConstraints::getMandatoryConstraintNames(WebVector<WebString>& names) const
+void WebMediaConstraints::getMandatoryConstraints(WebVector<WebMediaConstraint>& constraints) const
{
ASSERT(!isNull());
- Vector<String> constraintNames;
- m_private->getMandatoryConstraintNames(constraintNames);
- WebVector<WebString> result(constraintNames);
- names.swap(result);
+ Vector<MediaConstraint> mandatoryConstraints;
+ m_private->getMandatoryConstraints(mandatoryConstraints);
+ WebVector<WebMediaConstraint> result(mandatoryConstraints);
+ constraints.swap(result);
}
-void WebMediaConstraints::getOptionalConstraintNames(WebVector<WebString>& names) const
+void WebMediaConstraints::getOptionalConstraints(WebVector<WebMediaConstraint>& constraints) const
{
ASSERT(!isNull());
- Vector<String> constraintNames;
- m_private->getOptionalConstraintNames(constraintNames);
- WebVector<WebString> result(constraintNames);
- names.swap(result);
+ Vector<MediaConstraint> optionalConstraints;
+ m_private->getOptionalConstraints(optionalConstraints);
+ WebVector<WebMediaConstraint> result(optionalConstraints);
+ constraints.swap(result);
}
bool WebMediaConstraints::getMandatoryConstraintValue(const WebString& name, WebString& value) const
diff --git a/Source/WebCore/platform/chromium/support/WebRTCDataChannel.cpp b/Source/WebCore/platform/chromium/support/WebRTCDataChannel.cpp
new file mode 100644
index 000000000..5c1479f81
--- /dev/null
+++ b/Source/WebCore/platform/chromium/support/WebRTCDataChannel.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <public/WebRTCDataChannel.h>
+
+#include "RTCDataChannelDescriptor.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class ExtraDataContainer : public WebCore::RTCDataChannelDescriptor::ExtraData {
+public:
+ ExtraDataContainer(WebRTCDataChannel::ExtraData* extraData) : m_extraData(WTF::adoptPtr(extraData)) { }
+
+ WebRTCDataChannel::ExtraData* extraData() { return m_extraData.get(); }
+
+private:
+ OwnPtr<WebRTCDataChannel::ExtraData> m_extraData;
+};
+
+WebRTCDataChannel::WebRTCDataChannel(const PassRefPtr<RTCDataChannelDescriptor>& dataChannel)
+ : m_private(dataChannel)
+{
+}
+
+WebRTCDataChannel::WebRTCDataChannel(RTCDataChannelDescriptor* dataChannel)
+ : m_private(dataChannel)
+{
+}
+
+void WebRTCDataChannel::initialize(const WebString& label, bool reliable)
+{
+ m_private = RTCDataChannelDescriptor::create(label, reliable);
+}
+
+void WebRTCDataChannel::assign(const WebRTCDataChannel& other)
+{
+ m_private = other.m_private;
+}
+
+void WebRTCDataChannel::reset()
+{
+ m_private.reset();
+}
+
+WebRTCDataChannel::operator PassRefPtr<WebCore::RTCDataChannelDescriptor>() const
+{
+ return m_private.get();
+}
+
+WebRTCDataChannel::operator WebCore::RTCDataChannelDescriptor*() const
+{
+ return m_private.get();
+}
+
+WebRTCDataChannel::ExtraData* WebRTCDataChannel::extraData() const
+{
+ RefPtr<RTCDataChannelDescriptor::ExtraData> data = m_private->extraData();
+ if (!data)
+ return 0;
+ return static_cast<ExtraDataContainer*>(data.get())->extraData();
+}
+
+void WebRTCDataChannel::setExtraData(ExtraData* extraData)
+{
+ m_private->setExtraData(adoptRef(new ExtraDataContainer(extraData)));
+}
+
+WebString WebRTCDataChannel::label() const
+{
+ ASSERT(!isNull());
+ return m_private->label();
+}
+
+bool WebRTCDataChannel::reliable() const
+{
+ ASSERT(!isNull());
+ return m_private->reliable();
+}
+
+void WebRTCDataChannel::setBufferedAmount(unsigned long bufferedAmount)
+{
+ ASSERT(!isNull());
+ m_private->setBufferedAmount(bufferedAmount);
+}
+
+void WebRTCDataChannel::readyStateChanged(ReadyState state)
+{
+ ASSERT(!isNull());
+ m_private->readyStateChanged(static_cast<RTCDataChannelDescriptor::ReadyState>(state));
+}
+
+void WebRTCDataChannel::dataArrived(const WebString& data)
+{
+ ASSERT(!isNull());
+ m_private->dataArrived(data);
+}
+
+void WebRTCDataChannel::dataArrived(const char* data, size_t dataLength)
+{
+ ASSERT(!isNull());
+ m_private->dataArrived(data, dataLength);
+}
+
+void WebRTCDataChannel::error()
+{
+ ASSERT(!isNull());
+ m_private->error();
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
+
diff --git a/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm b/Source/WebCore/platform/chromium/support/WebRTCStatsRequest.cpp
index bd6b38a75..63d99a0ce 100644
--- a/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm
+++ b/Source/WebCore/platform/chromium/support/WebRTCStatsRequest.cpp
@@ -1,5 +1,6 @@
+
/*
- * Copyright (C) 2011,2012 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,29 +29,63 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import "config.h"
-#import "LocalizedNumber.h"
+#include "config.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <public/WebMediaStreamComponent.h>
+#include <public/WebMediaStreamDescriptor.h>
+#include <public/WebRTCStatsRequest.h>
+#include <public/WebRTCStatsResponse.h>
+
+#include "RTCStatsRequest.h"
+#include "RTCStatsResponse.h"
+#include <wtf/PassOwnPtr.h>
+
+using namespace WebCore;
-#include "LocaleMac.h"
+namespace WebKit {
-namespace WebCore {
+WebRTCStatsRequest::WebRTCStatsRequest(const PassRefPtr<RTCStatsRequest>& request)
+ : m_private(request)
+{
+}
+
+void WebRTCStatsRequest::assign(const WebRTCStatsRequest& other)
+{
+ m_private = other.m_private;
+}
+
+void WebRTCStatsRequest::reset()
+{
+ m_private.reset();
+}
+
+WebRTCStatsResponse WebRTCStatsRequest::createResponse() const
+{
+ return WebRTCStatsResponse(m_private->createResponse());
+}
+
+bool WebRTCStatsRequest::hasSelector() const
+{
+ return m_private->hasSelector();
+}
-String convertToLocalizedNumber(const String& canonicalNumberString)
+const WebMediaStreamDescriptor WebRTCStatsRequest::stream() const
{
- return LocaleMac::currentLocale()->convertToLocalizedNumber(canonicalNumberString);
+ return WebMediaStreamDescriptor(m_private->stream());
}
-String convertFromLocalizedNumber(const String& localizedNumberString)
+const WebMediaStreamComponent WebRTCStatsRequest::component() const
{
- return LocaleMac::currentLocale()->convertFromLocalizedNumber(localizedNumberString);
+ return WebMediaStreamComponent(m_private->component());
}
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-String localizedDecimalSeparator()
+void WebRTCStatsRequest::requestSucceeded(const WebRTCStatsResponse& response) const
{
- return LocaleMac::currentLocale()->localizedDecimalSeparator();
+ m_private->requestSucceeded(response);
}
-#endif
-} // namespace WebCore
+} // namespace WebKit
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/chromium/support/WebRTCStatsResponse.cpp b/Source/WebCore/platform/chromium/support/WebRTCStatsResponse.cpp
new file mode 100644
index 000000000..e69c7595b
--- /dev/null
+++ b/Source/WebCore/platform/chromium/support/WebRTCStatsResponse.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <public/WebRTCStatsResponse.h>
+
+#include "RTCStatsResponseBase.h"
+#include <wtf/PassOwnPtr.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebRTCStatsResponse::WebRTCStatsResponse(const PassRefPtr<RTCStatsResponseBase>& request)
+ : m_private(request)
+{
+}
+
+void WebRTCStatsResponse::assign(const WebRTCStatsResponse& other)
+{
+ m_private = other.m_private;
+}
+
+void WebRTCStatsResponse::reset()
+{
+ m_private.reset();
+}
+
+WebRTCStatsResponse::operator WTF::PassRefPtr<WebCore::RTCStatsResponseBase>() const
+{
+ return m_private.get();
+}
+
+size_t WebRTCStatsResponse::addReport()
+{
+ return m_private->addReport();
+}
+
+void WebRTCStatsResponse::addElement(size_t report, bool isLocal, double timestamp)
+{
+ m_private->addElement(report, isLocal, timestamp);
+}
+
+void WebRTCStatsResponse::addStatistic(size_t report, bool isLocal, WebString name, WebString value)
+{
+ m_private->addStatistic(report, isLocal, name, value);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(MEDIA_STREAM)
+
diff --git a/Source/WebCore/platform/chromium/support/WebURLRequest.cpp b/Source/WebCore/platform/chromium/support/WebURLRequest.cpp
index f437b5164..e3851014f 100644
--- a/Source/WebCore/platform/chromium/support/WebURLRequest.cpp
+++ b/Source/WebCore/platform/chromium/support/WebURLRequest.cpp
@@ -195,7 +195,7 @@ void WebURLRequest::visitHTTPHeaderFields(WebHTTPHeaderVisitor* visitor) const
{
const HTTPHeaderMap& map = m_private->m_resourceRequest->httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
- visitor->visitHeader(it->first, it->second);
+ visitor->visitHeader(it->key, it->value);
}
WebHTTPBody WebURLRequest::httpBody() const
diff --git a/Source/WebCore/platform/chromium/support/WebURLResponse.cpp b/Source/WebCore/platform/chromium/support/WebURLResponse.cpp
index 9de3c01a0..2875978c8 100644
--- a/Source/WebCore/platform/chromium/support/WebURLResponse.cpp
+++ b/Source/WebCore/platform/chromium/support/WebURLResponse.cpp
@@ -261,7 +261,7 @@ void WebURLResponse::addHTTPHeaderField(const WebString& name, const WebString&
HTTPHeaderMap::AddResult result =
const_cast<HTTPHeaderMap*>(&map)->add(name, valueStr);
if (!result.isNewEntry)
- result.iterator->second.append(", " + valueStr);
+ result.iterator->value.append(", " + valueStr);
}
void WebURLResponse::clearHTTPHeaderField(const WebString& name)
@@ -275,7 +275,7 @@ void WebURLResponse::visitHTTPHeaderFields(WebHTTPHeaderVisitor* visitor) const
{
const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = map.begin(); it != map.end(); ++it)
- visitor->visitHeader(it->first, it->second);
+ visitor->visitHeader(it->key, it->value);
}
double WebURLResponse::lastModifiedDate() const
diff --git a/Source/WebCore/platform/efl/AsyncFileSystemEfl.cpp b/Source/WebCore/platform/efl/AsyncFileSystemEfl.cpp
new file mode 100644
index 000000000..a6608bbb4
--- /dev/null
+++ b/Source/WebCore/platform/efl/AsyncFileSystemEfl.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AsyncFileSystemEfl.h"
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "ExceptionCode.h"
+#include "LocalFileSystem.h"
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+bool AsyncFileSystem::isAvailable()
+{
+ return false;
+}
+
+PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create()
+{
+ return adoptPtr(new AsyncFileSystemEfl());
+}
+
+void AsyncFileSystem::openFileSystem(const String&, const String&, FileSystemType, bool, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystem::deleteFileSystem(const String&, const String&, FileSystemType, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+AsyncFileSystemEfl::AsyncFileSystemEfl()
+ : AsyncFileSystem()
+{
+}
+
+AsyncFileSystemEfl::~AsyncFileSystemEfl()
+{
+}
+
+void AsyncFileSystemEfl::move(const KURL&, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::copy(const KURL&, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::remove(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::removeRecursively(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::readMetadata(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::createFile(const KURL&, bool, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::createDirectory(const KURL&, bool, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::fileExists(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::directoryExists(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::readDirectory(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::createWriter(AsyncFileWriterClient*, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+void AsyncFileSystemEfl::createSnapshotFileAndReadMetadata(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/efl/AsyncFileSystemEfl.h b/Source/WebCore/platform/efl/AsyncFileSystemEfl.h
new file mode 100644
index 000000000..199b7c4ca
--- /dev/null
+++ b/Source/WebCore/platform/efl/AsyncFileSystemEfl.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AsyncFileSystemEfl_h
+#define AsyncFileSystemEfl_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "AsyncFileSystem.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class AsyncFileSystemCallbacks;
+
+class AsyncFileSystemEfl : public AsyncFileSystem {
+public:
+ AsyncFileSystemEfl();
+ virtual ~AsyncFileSystemEfl();
+
+ virtual void move(const KURL&, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void copy(const KURL&, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void remove(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void removeRecursively(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void readMetadata(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void createFile(const KURL&, bool, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void createDirectory(const KURL&, bool, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void fileExists(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void directoryExists(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void readDirectory(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void createWriter(AsyncFileWriterClient*, const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+ virtual void createSnapshotFileAndReadMetadata(const KURL&, PassOwnPtr<AsyncFileSystemCallbacks>);
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // AsyncFileSystemEfl_h
diff --git a/Source/WebCore/platform/efl/ClipboardEfl.cpp b/Source/WebCore/platform/efl/ClipboardEfl.cpp
index 884d387e5..dd4ac20cf 100644
--- a/Source/WebCore/platform/efl/ClipboardEfl.cpp
+++ b/Source/WebCore/platform/efl/ClipboardEfl.cpp
@@ -76,10 +76,10 @@ bool ClipboardEfl::setData(const String&, const String&)
return false;
}
-HashSet<String> ClipboardEfl::types() const
+ListHashSet<String> ClipboardEfl::types() const
{
notImplemented();
- return HashSet<String>();
+ return ListHashSet<String>();
}
PassRefPtr<FileList> ClipboardEfl::files() const
diff --git a/Source/WebCore/platform/efl/ClipboardEfl.h b/Source/WebCore/platform/efl/ClipboardEfl.h
index 3da598ecb..904eb5217 100644
--- a/Source/WebCore/platform/efl/ClipboardEfl.h
+++ b/Source/WebCore/platform/efl/ClipboardEfl.h
@@ -39,7 +39,7 @@ public:
String getData(const String&) const;
bool setData(const String&, const String&);
- HashSet<String> types() const;
+ ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
IntPoint dragLocation() const;
diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp
index b9a8963c2..7272b00b9 100644
--- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp
+++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp
@@ -28,6 +28,7 @@
#include "RenderThemeEfl.h"
#include "CSSValueKeywords.h"
+#include "CairoUtilitiesEfl.h"
#include "FontDescription.h"
#include "GraphicsContext.h"
#include "HTMLInputElement.h"
@@ -162,27 +163,6 @@ void RenderThemeEfl::adjustSizeConstraints(RenderStyle* style, FormType type) co
style->setPaddingRight(desc->padding.right());
}
-static PassRefPtr<cairo_surface_t> createSurfaceForBackingStore(Ecore_Evas* ee)
-{
- ASSERT(ee);
-
- int width;
- int height;
- ecore_evas_geometry_get(ee, 0, 0, &width, &height);
- ASSERT(width > 0 && height > 0);
-
- unsigned char* buffer = static_cast<unsigned char*>(const_cast<void*>(ecore_evas_buffer_pixels_get(ee)));
- RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4));
-
- cairo_status_t status = cairo_surface_status(surface.get());
- if (status != CAIRO_STATUS_SUCCESS) {
- EINA_LOG_ERR("Could not create cairo surface: %s", cairo_status_to_string(status));
- return 0;
- }
-
- return surface;
-}
-
static bool isFormElementTooLargeToDisplay(const IntSize& elementSize)
{
// This limit of 20000 pixels is hardcoded inside edje -- anything above this size
@@ -1063,7 +1043,9 @@ bool RenderThemeEfl::emitMediaButtonSignal(FormType formType, MediaControlElemen
else if (mediaElementType == MediaSeekBackButton)
edje_object_signal_emit(entry->edje(), "seekbackward", "");
else if (mediaElementType == MediaEnterFullscreenButton)
- edje_object_signal_emit(entry->edje(), "fullscreen", "");
+ edje_object_signal_emit(entry->edje(), "fullscreen_enter", "");
+ else if (mediaElementType == MediaExitFullscreenButton)
+ edje_object_signal_emit(entry->edje(), "fullscreen_exit", "");
#if ENABLE(VIDEO_TRACK)
else if (mediaElementType == MediaShowClosedCaptionsButton)
edje_object_signal_emit(entry->edje(), "show_captions", "");
@@ -1093,15 +1075,21 @@ String RenderThemeEfl::formatMediaControlsCurrentTime(float currentTime, float d
return formatMediaControlsTime(currentTime) + " / " + formatMediaControlsTime(duration);
}
+bool RenderThemeEfl::hasOwnDisabledStateHandlingFor(ControlPart part) const
+{
+ return (part != MediaMuteButtonPart);
+}
+
bool RenderThemeEfl::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
Node* mediaNode = object->node() ? object->node()->shadowHost() : 0;
if (!mediaNode)
mediaNode = object->node();
- if (!mediaNode || (!mediaNode->hasTagName(videoTag)))
+ if (!mediaNode || !mediaNode->isElementNode() || !static_cast<Element*>(mediaNode)->isMediaElement())
return false;
- if (!emitMediaButtonSignal(FullScreenButton, MediaEnterFullscreenButton, rect))
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode);
+ if (!emitMediaButtonSignal(FullScreenButton, mediaElement->isFullscreen() ? MediaExitFullscreenButton : MediaEnterFullscreenButton, rect))
return false;
return paintThemePart(object, FullScreenButton, info, rect);
diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.h b/Source/WebCore/platform/efl/RenderThemeEfl.h
index 4ab589043..63b0f49a3 100644
--- a/Source/WebCore/platform/efl/RenderThemeEfl.h
+++ b/Source/WebCore/platform/efl/RenderThemeEfl.h
@@ -190,7 +190,7 @@ public:
virtual String extraFullScreenStyleSheet();
#endif
virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
- virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
+ virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const;
virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
index b64723a08..22ffac004 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp
@@ -39,6 +39,82 @@ inline static int getValidationResultValue(const ShHandle compiler, ShShaderInfo
return value;
}
+static bool getSymbolInfo(ShHandle compiler, ShShaderInfo symbolType, Vector<ANGLEShaderSymbol>& symbols)
+{
+ ShShaderInfo symbolMaxNameLengthType;
+
+ switch (symbolType) {
+ case SH_ACTIVE_ATTRIBUTES:
+ symbolMaxNameLengthType = SH_ACTIVE_ATTRIBUTE_MAX_LENGTH;
+ break;
+ case SH_ACTIVE_UNIFORMS:
+ symbolMaxNameLengthType = SH_ACTIVE_UNIFORM_MAX_LENGTH;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ int numSymbols = getValidationResultValue(compiler, symbolType);
+ if (numSymbols < 0)
+ return false;
+
+ int maxNameLength = getValidationResultValue(compiler, symbolMaxNameLengthType);
+ if (maxNameLength <= 1)
+ return false;
+
+ int maxMappedNameLength = getValidationResultValue(compiler, SH_MAPPED_NAME_MAX_LENGTH);
+ if (maxMappedNameLength <= 1)
+ return false;
+
+ // The maximum allowed symbol name length is 256 characters.
+ Vector<char, 256> nameBuffer(maxNameLength);
+ Vector<char, 256> mappedNameBuffer(maxMappedNameLength);
+
+ for (int i = 0; i < numSymbols; ++i) {
+ ANGLEShaderSymbol symbol;
+ int nameLength = -1;
+ switch (symbolType) {
+ case SH_ACTIVE_ATTRIBUTES:
+ symbol.symbolType = SHADER_SYMBOL_TYPE_ATTRIBUTE;
+ ShGetActiveAttrib(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.data(), mappedNameBuffer.data());
+ break;
+ case SH_ACTIVE_UNIFORMS:
+ symbol.symbolType = SHADER_SYMBOL_TYPE_UNIFORM;
+ ShGetActiveUniform(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.data(), mappedNameBuffer.data());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ if (nameLength <= 0)
+ return false;
+
+ // The ShGetActive* calls above are guaranteed to produce null-terminated strings for
+ // nameBuffer and mappedNameBuffer. Also, the character set for symbol names
+ // is a subset of Latin-1 as specified by the OpenGL ES Shading Language, Section 3.1 and
+ // WebGL, Section "Characters Outside the GLSL Source Character Set".
+
+ // If the variable is an array, add symbols for each array element
+ if (symbol.size > 1) {
+ for (int i = 0; i < symbol.size; i++) {
+ String name = nameBuffer.data();
+ String mappedName = mappedNameBuffer.data();
+ name.replace(name.length() - 2, 1, String::number(i));
+ mappedName.replace(mappedName.length() - 2, 1, String::number(i));
+ symbol.name = name;
+ symbol.mappedName = mappedName;
+ symbols.append(symbol);
+ }
+ } else {
+ symbol.name = String(nameBuffer.data());
+ symbol.mappedName = String(mappedNameBuffer.data());
+ symbols.append(symbol);
+ }
+ }
+ return true;
+}
+
ANGLEWebKitBridge::ANGLEWebKitBridge(ShShaderOutput shaderOutput, ShShaderSpec shaderSpec)
: builtCompilers(false)
, m_fragmentCompiler(0)
@@ -75,7 +151,7 @@ void ANGLEWebKitBridge::setResources(ShBuiltInResources resources)
m_resources = resources;
}
-bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions)
+bool ANGLEWebKitBridge::compileShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog, Vector<ANGLEShaderSymbol>& symbols, int extraCompileOptions)
{
if (!builtCompilers) {
m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, m_shaderSpec, m_shaderOutput, &m_resources);
@@ -97,7 +173,7 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
const char* const shaderSourceStrings[] = { shaderSource };
- bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE | extraCompileOptions);
+ bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | extraCompileOptions);
if (!validateSuccess) {
int logSize = getValidationResultValue(compiler, SH_INFO_LOG_LENGTH);
if (logSize > 1) {
@@ -118,35 +194,11 @@ bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShad
ShGetObjectCode(compiler, translationBuffer.get());
translatedShaderSource = translationBuffer.get();
}
-
- return true;
-}
-
-bool ANGLEWebKitBridge::getUniforms(ShShaderType shaderType, Vector<ANGLEShaderSymbol> &symbols)
-{
- const ShHandle compiler = (shaderType == SH_VERTEX_SHADER ? m_vertexCompiler : m_fragmentCompiler);
-
- int numUniforms = getValidationResultValue(compiler, SH_ACTIVE_UNIFORMS);
- if (numUniforms < 0)
+
+ if (!getSymbolInfo(compiler, SH_ACTIVE_ATTRIBUTES, symbols))
return false;
- if (!numUniforms)
- return true;
-
- int maxNameLength = getValidationResultValue(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH);
- if (maxNameLength <= 1)
+ if (!getSymbolInfo(compiler, SH_ACTIVE_UNIFORMS, symbols))
return false;
- OwnArrayPtr<char> nameBuffer = adoptArrayPtr(new char[maxNameLength]);
-
- for (int i = 0; i < numUniforms; ++i) {
- ANGLEShaderSymbol symbol;
- symbol.symbolType = SHADER_SYMBOL_TYPE_UNIFORM;
- int nameLength = -1;
- ShGetActiveUniform(compiler, i, &nameLength, &symbol.size, &symbol.dataType, nameBuffer.get(), 0);
- if (nameLength <= 0)
- return false;
- symbol.name = String::fromUTF8(nameBuffer.get(), nameLength);
- symbols.append(symbol);
- }
return true;
}
diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
index 19c504eb3..178d3bddc 100644
--- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
+++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h
@@ -50,15 +50,17 @@ enum ANGLEShaderSymbolType {
struct ANGLEShaderSymbol {
ANGLEShaderSymbolType symbolType;
String name;
+ String mappedName;
ShDataType dataType;
int size;
bool isSampler()
{
- return dataType == SH_SAMPLER_2D
+ return symbolType == SHADER_SYMBOL_TYPE_UNIFORM
+ && (dataType == SH_SAMPLER_2D
|| dataType == SH_SAMPLER_CUBE
|| dataType == SH_SAMPLER_2D_RECT_ARB
- || dataType == SH_SAMPLER_EXTERNAL_OES;
+ || dataType == SH_SAMPLER_EXTERNAL_OES);
}
};
@@ -71,12 +73,7 @@ public:
ShBuiltInResources getResources() { return m_resources; }
void setResources(ShBuiltInResources);
- bool validateShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions = 0);
-
- // Get the uniforms for the last validated shader of type ShShaderType.
- // For this function to work, you must use the SH_ATTRIBUTES_UNIFORMS compile option during validation.
- // Returns false if an unexpected error occurred in ANGLE.
- bool getUniforms(ShShaderType, Vector<ANGLEShaderSymbol> &symbols);
+ bool compileShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, Vector<ANGLEShaderSymbol>& symbols, int extraCompileOptions = 0);
private:
diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp
index d0a2aabd1..def072ee0 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.cpp
+++ b/Source/WebCore/platform/graphics/BitmapImage.cpp
@@ -580,13 +580,18 @@ void BitmapImage::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
info.addMember(m_source);
info.addMember(m_frameTimer);
info.addMember(m_frames);
- for (unsigned i = 0; i < m_frameCount; ++i) {
+}
+
+void FrameData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image);
#if OS(WINCE) && !PLATFORM(QT)
- info.addRawBuffer(m_frames[i].m_frame.get(), m_frames[i].m_frameBytes);
+ info.addRawBuffer(m_frame.get(), m_frameBytes);
+#elif USE(SKIA)
+ info.addMember(m_frame);
#else
- info.addRawBuffer(m_frames[i].m_frame, m_frames[i].m_frameBytes);
+ info.addRawBuffer(m_frame, m_frameBytes);
#endif
- }
}
}
diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h
index 3f23dcedf..8fedc3e50 100644
--- a/Source/WebCore/platform/graphics/BitmapImage.h
+++ b/Source/WebCore/platform/graphics/BitmapImage.h
@@ -88,6 +88,8 @@ public:
// Returns whether there was cached image data to clear.
bool clear(bool clearMetadata);
+ void reportMemoryUsage(MemoryObjectInfo*) const;
+
NativeImagePtr m_frame;
ImageOrientation m_orientation;
float m_duration;
diff --git a/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp b/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp
index 30d8d3d41..423d14726 100644
--- a/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp
+++ b/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp
@@ -53,7 +53,7 @@ void DisplayRefreshMonitorClient::fireDisplayRefreshIfNeeded(double timestamp)
}
DisplayRefreshMonitor::DisplayRefreshMonitor(PlatformDisplayID displayID)
- : m_timestamp(0)
+ : m_monotonicAnimationStartTime(0)
, m_active(true)
, m_scheduled(false)
, m_previousFrameDone(true)
@@ -91,7 +91,7 @@ bool DisplayRefreshMonitor::removeClient(DisplayRefreshMonitorClient* client)
void DisplayRefreshMonitor::displayDidRefresh()
{
- double timestamp;
+ double monotonicAnimationStartTime;
{
MutexLocker lock(m_mutex);
if (!m_scheduled)
@@ -100,7 +100,7 @@ void DisplayRefreshMonitor::displayDidRefresh()
m_unscheduledFireCount = 0;
m_scheduled = false;
- timestamp = m_timestamp;
+ monotonicAnimationStartTime = m_monotonicAnimationStartTime;
}
// The call back can cause all our clients to be unregistered, so we need to protect
@@ -110,7 +110,7 @@ void DisplayRefreshMonitor::displayDidRefresh()
Vector<DisplayRefreshMonitorClient*> clients;
copyToVector(m_clients, clients);
for (size_t i = 0; i < clients.size(); ++i)
- clients[i]->fireDisplayRefreshIfNeeded(timestamp);
+ clients[i]->fireDisplayRefreshIfNeeded(monotonicAnimationStartTime);
{
MutexLocker lock(m_mutex);
@@ -136,8 +136,8 @@ DisplayRefreshMonitor* DisplayRefreshMonitorManager::ensureMonitorForClient(Disp
m_monitors.add(client->m_displayID, monitor.release());
return result;
}
-
- return it->second.get();
+ it->value->addClient(client);
+ return it->value.get();
}
void DisplayRefreshMonitorManager::registerClient(DisplayRefreshMonitorClient* client)
@@ -157,7 +157,7 @@ void DisplayRefreshMonitorManager::unregisterClient(DisplayRefreshMonitorClient*
if (it == m_monitors.end())
return;
- DisplayRefreshMonitor* monitor = it->second.get();
+ DisplayRefreshMonitor* monitor = it->value.get();
if (monitor->removeClient(client)) {
if (!monitor->hasClients())
m_monitors.remove(it);
diff --git a/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h b/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h
index 6917d6e7b..ddf4b357a 100644
--- a/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h
+++ b/Source/WebCore/platform/graphics/DisplayRefreshMonitor.h
@@ -121,7 +121,7 @@ private:
void displayDidRefresh();
static void handleDisplayRefreshedNotificationOnMainThread(void* data);
- double m_timestamp;
+ double m_monotonicAnimationStartTime;
bool m_active;
bool m_scheduled;
bool m_previousFrameDone;
diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h
index 5f28afb3b..48b26ce12 100644
--- a/Source/WebCore/platform/graphics/Extensions3D.h
+++ b/Source/WebCore/platform/graphics/Extensions3D.h
@@ -188,6 +188,22 @@ public:
virtual void insertEventMarkerEXT(const String&) = 0;
virtual void pushGroupMarkerEXT(const String&) = 0;
virtual void popGroupMarkerEXT(void) = 0;
+
+ virtual bool isNVIDIA() = 0;
+ virtual bool isAMD() = 0;
+ virtual bool isIntel() = 0;
+ virtual String vendor() = 0;
+
+ // If this method returns false then the system *definitely* does not support multisampling.
+ // It does not necessarily say the system does support it - callers must attempt to construct
+ // multisampled renderbuffers and check framebuffer completeness.
+ // Ports should implement this to return false on configurations where it is known
+ // that multisampling is not available.
+ virtual bool maySupportMultisampling() = 0;
+
+ // Some configurations have bugs regarding built-in functions in their OpenGL drivers
+ // that must be avoided. Ports should implement this flag such configurations.
+ virtual bool requiresBuiltInFunctionEmulation() = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/FloatSize.h b/Source/WebCore/platform/graphics/FloatSize.h
index c029c5a95..2c9cc18e3 100644
--- a/Source/WebCore/platform/graphics/FloatSize.h
+++ b/Source/WebCore/platform/graphics/FloatSize.h
@@ -121,7 +121,7 @@ public:
}
#if PLATFORM(QT)
- FloatSize(const QSizeF&);
+ explicit FloatSize(const QSizeF&);
operator QSizeF() const;
#endif
diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp
index 714fa9a84..1b2e9b8d9 100644
--- a/Source/WebCore/platform/graphics/Font.cpp
+++ b/Source/WebCore/platform/graphics/Font.cpp
@@ -64,6 +64,8 @@ const uint8_t Font::s_roundingHackCharacterTable[256] = {
Font::CodePath Font::s_codePath = Auto;
+TypesettingFeatures Font::s_defaultTypesettingFeatures = 0;
+
// ============================================================================================
// Font Implementation (Cross-Platform Portion)
// ============================================================================================
@@ -86,7 +88,7 @@ Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing)
}
Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMode fontSmoothingMode)
- : m_fontList(FontFallbackList::create())
+ : m_fontFallbackList(FontFallbackList::create())
, m_letterSpacing(0)
, m_wordSpacing(0)
, m_isPlatformFont(true)
@@ -94,12 +96,12 @@ Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMo
m_fontDescription.setUsePrinterFont(isPrinterFont);
m_fontDescription.setFontSmoothing(fontSmoothingMode);
m_needsTranscoding = fontTranscoder().needsTranscoding(fontDescription());
- m_fontList->setPlatformFont(fontData);
+ m_fontFallbackList->setPlatformFont(fontData);
}
Font::Font(const Font& other)
: m_fontDescription(other.m_fontDescription)
- , m_fontList(other.m_fontList)
+ , m_fontFallbackList(other.m_fontFallbackList)
, m_letterSpacing(other.m_letterSpacing)
, m_wordSpacing(other.m_wordSpacing)
, m_isPlatformFont(other.m_isPlatformFont)
@@ -110,7 +112,7 @@ Font::Font(const Font& other)
Font& Font::operator=(const Font& other)
{
m_fontDescription = other.m_fontDescription;
- m_fontList = other.m_fontList;
+ m_fontFallbackList = other.m_fontFallbackList;
m_letterSpacing = other.m_letterSpacing;
m_wordSpacing = other.m_wordSpacing;
m_isPlatformFont = other.m_isPlatformFont;
@@ -125,15 +127,15 @@ bool Font::operator==(const Font& other) const
if (loadingCustomFonts() || other.loadingCustomFonts())
return false;
- FontSelector* first = m_fontList ? m_fontList->fontSelector() : 0;
- FontSelector* second = other.m_fontList ? other.m_fontList->fontSelector() : 0;
+ FontSelector* first = m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
+ FontSelector* second = other.m_fontFallbackList ? other.m_fontFallbackList->fontSelector() : 0;
return first == second
- && m_fontDescription == other.m_fontDescription
- && m_letterSpacing == other.m_letterSpacing
- && m_wordSpacing == other.m_wordSpacing
- && (m_fontList ? m_fontList->fontSelectorVersion() : 0) == (other.m_fontList ? other.m_fontList->fontSelectorVersion() : 0)
- && (m_fontList ? m_fontList->generation() : 0) == (other.m_fontList ? other.m_fontList->generation() : 0);
+ && m_fontDescription == other.m_fontDescription
+ && m_letterSpacing == other.m_letterSpacing
+ && m_wordSpacing == other.m_wordSpacing
+ && (m_fontFallbackList ? m_fontFallbackList->fontSelectorVersion() : 0) == (other.m_fontFallbackList ? other.m_fontFallbackList->fontSelectorVersion() : 0)
+ && (m_fontFallbackList ? m_fontFallbackList->generation() : 0) == (other.m_fontFallbackList ? other.m_fontFallbackList->generation() : 0);
}
void Font::update(PassRefPtr<FontSelector> fontSelector) const
@@ -143,9 +145,9 @@ void Font::update(PassRefPtr<FontSelector> fontSelector) const
// style anyway. Other copies are transient, e.g., the state in the GraphicsContext, and
// won't stick around long enough to get you in trouble). Still, this is pretty disgusting,
// and could eventually be rectified by using RefPtrs for Fonts themselves.
- if (!m_fontList)
- m_fontList = FontFallbackList::create();
- m_fontList->invalidate(fontSelector);
+ if (!m_fontFallbackList)
+ m_fontFallbackList = FontFallbackList::create();
+ m_fontFallbackList->invalidate(fontSelector);
}
void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
@@ -185,7 +187,7 @@ float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo
// If the complex text implementation cannot return fallback fonts, avoid
// returning them for simple text as well.
static bool returnFallbackFonts = canReturnFallbackFontsForComplexText();
- return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
+ return floatWidthForSimpleText(run, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
}
return floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
@@ -202,7 +204,7 @@ float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) con
glyphName = "";
if (codePath(run) != Complex)
- return floatWidthForSimpleText(run, 0);
+ return floatWidthForSimpleText(run);
return floatWidthForComplexText(run);
}
@@ -218,7 +220,7 @@ void Font::deleteLayout(TextLayout*)
{
}
-float Font::width(TextLayout&, unsigned, unsigned)
+float Font::width(TextLayout&, unsigned, unsigned, HashSet<const SimpleFontData*>*)
{
ASSERT_NOT_REACHED();
return 0;
@@ -289,6 +291,16 @@ Font::CodePath Font::codePath()
return s_codePath;
}
+void Font::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)
+{
+ s_defaultTypesettingFeatures = typesettingFeatures;
+}
+
+TypesettingFeatures Font::defaultTypesettingFeatures()
+{
+ return s_defaultTypesettingFeatures;
+}
+
Font::CodePath Font::codePath(const TextRun& run) const
{
if (s_codePath != Auto)
@@ -302,7 +314,7 @@ Font::CodePath Font::codePath(const TextRun& run) const
if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
return Complex;
- if (run.length() > 1 && typesettingFeatures())
+ if (run.length() > 1 && !WidthIterator::supportsTypesettingFeatures(*this))
return Complex;
if (!run.characterScanForCodePath())
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index a259dab07..aabcb2e70 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -51,7 +51,6 @@ class FontMetrics;
class FontPlatformData;
class FontSelector;
class GlyphBuffer;
-class GlyphPageTreeNode;
class GraphicsContext;
class RenderText;
class TextLayout;
@@ -106,7 +105,7 @@ public:
PassOwnPtr<TextLayout> createLayout(RenderText*, float xPos, bool collapseWhiteSpace) const;
static void deleteLayout(TextLayout*);
- static float width(TextLayout&, unsigned from, unsigned len);
+ static float width(TextLayout&, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts = 0);
int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
@@ -125,7 +124,19 @@ public:
TypesettingFeatures typesettingFeatures() const
{
TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode();
- TypesettingFeatures features = textRenderingMode == OptimizeLegibility || textRenderingMode == GeometricPrecision ? Kerning | Ligatures : 0;
+ TypesettingFeatures features = s_defaultTypesettingFeatures;
+
+ switch(textRenderingMode) {
+ case AutoTextRendering:
+ break;
+ case OptimizeSpeed:
+ features &= ~(Kerning | Ligatures);
+ break;
+ case GeometricPrecision:
+ case OptimizeLegibility:
+ features |= Kerning | Ligatures;
+ break;
+ }
switch (m_fontDescription.kerning()) {
case FontDescription::NoneKerning:
@@ -173,7 +184,10 @@ public:
const SimpleFontData* primaryFont() const;
const FontData* fontDataAt(unsigned) const;
- GlyphData glyphDataForCharacter(UChar32, bool mirror, FontDataVariant = AutoVariant) const;
+ inline GlyphData glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant = AutoVariant) const
+ {
+ return glyphDataAndPageForCharacter(c, mirror, variant).first;
+ }
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
const SimpleFontData* fontDataForCombiningCharacterSequence(const UChar*, size_t length, FontDataVariant) const;
#endif
@@ -209,7 +223,7 @@ private:
void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
void drawGlyphBuffer(GraphicsContext*, const TextRun&, const GlyphBuffer&, const FloatPoint&) const;
void drawEmphasisMarks(GraphicsContext*, const TextRun&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
- float floatWidthForSimpleText(const TextRun&, GlyphBuffer*, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
FloatRect selectionRectForSimpleText(const TextRun&, const FloatPoint&, int h, int from, int to) const;
@@ -235,6 +249,9 @@ public:
static CodePath codePath();
static CodePath s_codePath;
+ static void setDefaultTypesettingFeatures(TypesettingFeatures);
+ static TypesettingFeatures defaultTypesettingFeatures();
+
static const uint8_t s_roundingHackCharacterTable[256];
static bool isRoundingHackCharacter(UChar32 c)
{
@@ -262,20 +279,22 @@ public:
static String normalizeSpaces(const UChar*, unsigned length);
bool needsTranscoding() const { return m_needsTranscoding; }
- FontFallbackList* fontList() const { return m_fontList.get(); }
+ FontFallbackList* fontList() const { return m_fontFallbackList.get(); }
private:
bool loadingCustomFonts() const
{
- return m_fontList && m_fontList->loadingCustomFonts();
+ return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
}
#if PLATFORM(QT)
void initFormatForTextLayout(QTextLayout*) const;
#endif
+ static TypesettingFeatures s_defaultTypesettingFeatures;
+
FontDescription m_fontDescription;
- mutable RefPtr<FontFallbackList> m_fontList;
+ mutable RefPtr<FontFallbackList> m_fontFallbackList;
short m_letterSpacing;
short m_wordSpacing;
bool m_isPlatformFont;
@@ -288,25 +307,25 @@ inline Font::~Font()
inline const SimpleFontData* Font::primaryFont() const
{
- ASSERT(m_fontList);
- return m_fontList->primarySimpleFontData(this);
+ ASSERT(m_fontFallbackList);
+ return m_fontFallbackList->primarySimpleFontData(this);
}
inline const FontData* Font::fontDataAt(unsigned index) const
{
- ASSERT(m_fontList);
- return m_fontList->fontDataAt(this, index);
+ ASSERT(m_fontFallbackList);
+ return m_fontFallbackList->fontDataAt(this, index);
}
inline bool Font::isFixedPitch() const
{
- ASSERT(m_fontList);
- return m_fontList->isFixedPitch(this);
+ ASSERT(m_fontFallbackList);
+ return m_fontFallbackList->isFixedPitch(this);
}
inline FontSelector* Font::fontSelector() const
{
- return m_fontList ? m_fontList->fontSelector() : 0;
+ return m_fontFallbackList ? m_fontFallbackList->fontSelector() : 0;
}
inline float Font::tabWidth(const SimpleFontData& fontData, unsigned tabSize, float position) const
diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp
index 9cab2fa0e..3fea6c235 100644
--- a/Source/WebCore/platform/graphics/FontCache.cpp
+++ b/Source/WebCore/platform/graphics/FontCache.cpp
@@ -34,7 +34,6 @@
#include "FontFallbackList.h"
#include "FontPlatformData.h"
#include "FontSelector.h"
-#include "GlyphPageTreeNode.h"
#include "OpenTypeVerticalData.h"
#include "WebKitFontFamilyNames.h"
#include <wtf/HashMap.h>
@@ -211,7 +210,7 @@ FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fo
gFontPlatformDataCache->set(key, result);
foundResult = result;
} else {
- result = it->second;
+ result = it->value;
foundResult = true;
}
@@ -229,7 +228,7 @@ FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fo
}
#if ENABLE(OPENTYPE_VERTICAL)
-typedef HashMap<FontCache::FontFileKey, OwnPtr<OpenTypeVerticalData> > FontVerticalDataCache;
+typedef HashMap<FontCache::FontFileKey, OwnPtr<OpenTypeVerticalData>, WTF::IntHash<FontCache::FontFileKey>, WTF::UnsignedWithZeroKeyHashTraits<FontCache::FontFileKey> > FontVerticalDataCache;
FontVerticalDataCache& fontVerticalDataCacheInstance()
{
@@ -242,7 +241,7 @@ OpenTypeVerticalData* FontCache::getVerticalData(const FontFileKey& key, const F
FontVerticalDataCache& fontVerticalDataCache = fontVerticalDataCacheInstance();
FontVerticalDataCache::iterator result = fontVerticalDataCache.find(key);
if (result != fontVerticalDataCache.end())
- return result.get()->second.get();
+ return result.get()->value.get();
OpenTypeVerticalData* verticalData = new OpenTypeVerticalData(platformData);
if (!verticalData->isOpenType()) {
@@ -286,7 +285,7 @@ struct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> {
}
};
-typedef HashMap<FontPlatformData, pair<SimpleFontData*, unsigned>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache;
+typedef HashMap<FontPlatformData, pair<RefPtr<SimpleFontData>, unsigned>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache;
static FontDataCache* gFontDataCache = 0;
@@ -297,9 +296,9 @@ const int cTargetInactiveFontData = 200;
const int cMaxInactiveFontData = 50; // Pretty Low Threshold
const int cTargetInactiveFontData = 30;
#endif
-static ListHashSet<const SimpleFontData*>* gInactiveFontData = 0;
+static ListHashSet<RefPtr<SimpleFontData> >* gInactiveFontData = 0;
-SimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName, ShouldRetain shouldRetain)
{
FontPlatformData* platformData = getCachedFontPlatformData(fontDescription, family, checkingAlternateName);
if (!platformData)
@@ -308,7 +307,7 @@ SimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescript
return getCachedFontData(platformData, shouldRetain);
}
-SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* platformData, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getCachedFontData(const FontPlatformData* platformData, ShouldRetain shouldRetain)
{
if (!platformData)
return 0;
@@ -320,37 +319,37 @@ SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* platformDat
if (!gFontDataCache) {
gFontDataCache = new FontDataCache;
- gInactiveFontData = new ListHashSet<const SimpleFontData*>;
+ gInactiveFontData = new ListHashSet<RefPtr<SimpleFontData> >;
}
FontDataCache::iterator result = gFontDataCache->find(*platformData);
if (result == gFontDataCache->end()) {
- pair<SimpleFontData*, unsigned> newValue(new SimpleFontData(*platformData), shouldRetain == Retain ? 1 : 0);
+ pair<RefPtr<SimpleFontData>, unsigned> newValue(SimpleFontData::create(*platformData), shouldRetain == Retain ? 1 : 0);
gFontDataCache->set(*platformData, newValue);
if (shouldRetain == DoNotRetain)
gInactiveFontData->add(newValue.first);
- return newValue.first;
+ return newValue.first.release();
}
- if (!result.get()->second.second) {
- ASSERT(gInactiveFontData->contains(result.get()->second.first));
- gInactiveFontData->remove(result.get()->second.first);
+ if (!result.get()->value.second) {
+ ASSERT(gInactiveFontData->contains(result.get()->value.first));
+ gInactiveFontData->remove(result.get()->value.first);
}
if (shouldRetain == Retain)
- result.get()->second.second++;
- else if (!result.get()->second.second) {
+ result.get()->value.second++;
+ else if (!result.get()->value.second) {
// If shouldRetain is DoNotRetain and count is 0, we want to remove the fontData from
// gInactiveFontData (above) and re-add here to update LRU position.
- gInactiveFontData->add(result.get()->second.first);
+ gInactiveFontData->add(result.get()->value.first);
}
- return result.get()->second.first;
+ return result.get()->value.first;
}
SimpleFontData* FontCache::getNonRetainedLastResortFallbackFont(const FontDescription& fontDescription)
{
- return getLastResortFallbackFont(fontDescription, DoNotRetain);
+ return getLastResortFallbackFont(fontDescription, DoNotRetain).leakRef();
}
void FontCache::releaseFontData(const SimpleFontData* fontData)
@@ -361,9 +360,9 @@ void FontCache::releaseFontData(const SimpleFontData* fontData)
FontDataCache::iterator it = gFontDataCache->find(fontData->platformData());
ASSERT(it != gFontDataCache->end());
- ASSERT(it->second.second);
- if (!--it->second.second)
- gInactiveFontData->add(fontData);
+ ASSERT(it->value.second);
+ if (!--it->value.second)
+ gInactiveFontData->add(it->value.first);
}
void FontCache::purgeInactiveFontDataIfNeeded()
@@ -383,11 +382,11 @@ void FontCache::purgeInactiveFontData(int count)
isPurging = true;
- Vector<const SimpleFontData*, 20> fontDataToDelete;
- ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontData->end();
- ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontData->begin();
+ Vector<RefPtr<SimpleFontData>, 20> fontDataToDelete;
+ ListHashSet<RefPtr<SimpleFontData> >::iterator end = gInactiveFontData->end();
+ ListHashSet<RefPtr<SimpleFontData> >::iterator it = gInactiveFontData->begin();
for (int i = 0; i < count && it != end; ++it, ++i) {
- const SimpleFontData* fontData = *it.get();
+ RefPtr<SimpleFontData>& fontData = *it.get();
gFontDataCache->remove(fontData->platformData());
// We should not delete SimpleFontData here because deletion can modify gInactiveFontData. See http://trac.webkit.org/changeset/44011
fontDataToDelete.append(fontData);
@@ -401,17 +400,15 @@ void FontCache::purgeInactiveFontData(int count)
gInactiveFontData->remove(gInactiveFontData->begin());
}
- size_t fontDataToDeleteCount = fontDataToDelete.size();
- for (size_t i = 0; i < fontDataToDeleteCount; ++i)
- delete fontDataToDelete[i];
+ fontDataToDelete.clear();
if (gFontPlatformDataCache) {
Vector<FontPlatformDataCacheKey> keysToRemove;
keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size());
FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end();
for (FontPlatformDataCache::iterator platformData = gFontPlatformDataCache->begin(); platformData != platformDataEnd; ++platformData) {
- if (platformData->second && !gFontDataCache->contains(*platformData->second))
- keysToRemove.append(platformData->first);
+ if (platformData->value && !gFontDataCache->contains(*platformData->value))
+ keysToRemove.append(platformData->key);
}
size_t keysToRemoveCount = keysToRemove.size();
@@ -425,20 +422,20 @@ void FontCache::purgeInactiveFontData(int count)
// Mark & sweep unused verticalData
FontVerticalDataCache::iterator verticalDataEnd = fontVerticalDataCache.end();
for (FontVerticalDataCache::iterator verticalData = fontVerticalDataCache.begin(); verticalData != verticalDataEnd; ++verticalData) {
- if (verticalData->second)
- verticalData->second->m_inFontCache = false;
+ if (verticalData->value)
+ verticalData->value->m_inFontCache = false;
}
FontDataCache::iterator fontDataEnd = gFontDataCache->end();
for (FontDataCache::iterator fontData = gFontDataCache->begin(); fontData != fontDataEnd; ++fontData) {
- OpenTypeVerticalData* verticalData = const_cast<OpenTypeVerticalData*>(fontData->second.first->verticalData());
+ OpenTypeVerticalData* verticalData = const_cast<OpenTypeVerticalData*>(fontData->value.first->verticalData());
if (verticalData)
verticalData->m_inFontCache = true;
}
Vector<FontFileKey> keysToRemove;
keysToRemove.reserveInitialCapacity(fontVerticalDataCache.size());
for (FontVerticalDataCache::iterator verticalData = fontVerticalDataCache.begin(); verticalData != verticalDataEnd; ++verticalData) {
- if (!verticalData->second || !verticalData->second->m_inFontCache)
- keysToRemove.append(verticalData->first);
+ if (!verticalData->value || !verticalData->value->m_inFontCache)
+ keysToRemove.append(verticalData->key);
}
for (size_t i = 0, count = keysToRemove.size(); i < count; ++i)
fontVerticalDataCache.take(keysToRemove[i]);
@@ -462,9 +459,9 @@ size_t FontCache::inactiveFontDataCount()
return 0;
}
-const FontData* FontCache::getFontData(const Font& font, int& familyIndex, FontSelector* fontSelector)
+PassRefPtr<FontData> FontCache::getFontData(const Font& font, int& familyIndex, FontSelector* fontSelector)
{
- FontData* result = 0;
+ RefPtr<FontData> result;
int startIndex = familyIndex;
const FontFamily* startFamily = &font.fontDescription().family();
@@ -498,14 +495,14 @@ const FontData* FontCache::getFontData(const Font& font, int& familyIndex, FontS
if (fontSelector) {
// Try the user's preferred standard font.
- if (FontData* data = fontSelector->getFontData(font.fontDescription(), standardFamily))
- return data;
+ if (RefPtr<FontData> data = fontSelector->getFontData(font.fontDescription(), standardFamily))
+ return data.release();
}
// Still no result. Hand back our last resort fallback font.
result = getLastResortFallbackFont(font.fontDescription());
}
- return result;
+ return result.release();
}
static HashSet<FontSelector*>* gClients;
diff --git a/Source/WebCore/platform/graphics/FontCache.h b/Source/WebCore/platform/graphics/FontCache.h
index 12fb8a328..3ae533475 100644
--- a/Source/WebCore/platform/graphics/FontCache.h
+++ b/Source/WebCore/platform/graphics/FontCache.h
@@ -32,6 +32,8 @@
#include <limits.h>
#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
#include <wtf/unicode/Unicode.h>
@@ -61,11 +63,11 @@ public:
enum ShouldRetain { Retain, DoNotRetain };
- const FontData* getFontData(const Font&, int& familyIndex, FontSelector*);
+ PassRefPtr<FontData> getFontData(const Font&, int& familyIndex, FontSelector*);
void releaseFontData(const SimpleFontData*);
// This method is implemented by the platform.
- const SimpleFontData* getFontDataForCharacters(const Font&, const UChar* characters, int length);
+ PassRefPtr<SimpleFontData> getFontDataForCharacters(const Font&, const UChar* characters, int length);
// Also implemented by the platform.
void platformInit();
@@ -85,8 +87,8 @@ public:
void getTraitsInFamily(const AtomicString&, Vector<unsigned>&);
- SimpleFontData* getCachedFontData(const FontDescription&, const AtomicString&, bool checkingAlternateName = false, ShouldRetain = Retain);
- SimpleFontData* getLastResortFallbackFont(const FontDescription&, ShouldRetain = Retain);
+ PassRefPtr<SimpleFontData> getCachedFontData(const FontDescription&, const AtomicString&, bool checkingAlternateName = false, ShouldRetain = Retain);
+ PassRefPtr<SimpleFontData> getLastResortFallbackFont(const FontDescription&, ShouldRetain = Retain);
SimpleFontData* getNonRetainedLastResortFallbackFont(const FontDescription&);
void addClient(FontSelector*);
@@ -100,9 +102,9 @@ public:
void purgeInactiveFontData(int count = INT_MAX);
#if PLATFORM(WIN)
- SimpleFontData* fontDataFromDescriptionAndLogFont(const FontDescription&, ShouldRetain, const LOGFONT& font, AtomicString& outFontFamilyName);
+ PassRefPtr<SimpleFontData> fontDataFromDescriptionAndLogFont(const FontDescription&, ShouldRetain, const LOGFONT&, AtomicString& outFontFamilyName);
#elif PLATFORM(CHROMIUM) && OS(WINDOWS)
- SimpleFontData* fontDataFromDescriptionAndLogFont(const FontDescription&, ShouldRetain, const LOGFONT& font, wchar_t* outFontFamilyName);
+ PassRefPtr<SimpleFontData> fontDataFromDescriptionAndLogFont(const FontDescription&, ShouldRetain, const LOGFONT&, wchar_t* outFontFamilyName);
#endif
#if ENABLE(OPENTYPE_VERTICAL)
@@ -139,10 +141,10 @@ private:
FontPlatformData* getCachedFontPlatformData(const FontDescription&, const AtomicString& family, bool checkingAlternateName = false);
// These methods are implemented by each platform.
- SimpleFontData* getSimilarFontPlatformData(const Font&);
+ PassRefPtr<SimpleFontData> getSimilarFontPlatformData(const Font&);
FontPlatformData* createFontPlatformData(const FontDescription&, const AtomicString& family);
- SimpleFontData* getCachedFontData(const FontPlatformData*, ShouldRetain = Retain);
+ PassRefPtr<SimpleFontData> getCachedFontData(const FontPlatformData*, ShouldRetain = Retain);
// Don't purge if this count is > 0;
int m_purgePreventCount;
diff --git a/Source/WebCore/platform/graphics/FontData.h b/Source/WebCore/platform/graphics/FontData.h
index 3d35d2aec..6e6e19f98 100644
--- a/Source/WebCore/platform/graphics/FontData.h
+++ b/Source/WebCore/platform/graphics/FontData.h
@@ -29,13 +29,15 @@
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
class SimpleFontData;
-class FontData {
+class FontData : public RefCounted<FontData> {
WTF_MAKE_NONCOPYABLE(FontData); WTF_MAKE_FAST_ALLOCATED;
public:
FontData()
diff --git a/Source/WebCore/platform/graphics/FontFallbackList.cpp b/Source/WebCore/platform/graphics/FontFallbackList.cpp
index 6d11c09e3..74ab726d5 100644
--- a/Source/WebCore/platform/graphics/FontFallbackList.cpp
+++ b/Source/WebCore/platform/graphics/FontFallbackList.cpp
@@ -66,9 +66,9 @@ void FontFallbackList::releaseFontData()
{
unsigned numFonts = m_fontList.size();
for (unsigned i = 0; i < numFonts; ++i) {
- if (!m_fontList[i].second) {
- ASSERT(!m_fontList[i].first->isSegmented());
- fontCache()->releaseFontData(static_cast<const SimpleFontData*>(m_fontList[i].first));
+ if (!m_fontList[i]->isCustomFont()) {
+ ASSERT(!m_fontList[i]->isSegmented());
+ fontCache()->releaseFontData(static_cast<const SimpleFontData*>(m_fontList[i].get()));
}
}
}
@@ -91,7 +91,7 @@ void FontFallbackList::determinePitch(const Font* font) const
const FontData* FontFallbackList::fontDataAt(const Font* font, unsigned realizedFontIndex) const
{
if (realizedFontIndex < m_fontList.size())
- return m_fontList[realizedFontIndex].first; // This fallback font is already in our list.
+ return m_fontList[realizedFontIndex].get(); // This fallback font is already in our list.
// Make sure we're not passing in some crazy value here.
ASSERT(realizedFontIndex == m_fontList.size());
@@ -104,21 +104,21 @@ const FontData* FontFallbackList::fontDataAt(const Font* font, unsigned realized
// in |m_familyIndex|, so that we never scan the same spot in the list twice. getFontData will adjust our
// |m_familyIndex| as it scans for the right font to make.
ASSERT(fontCache()->generation() == m_generation);
- const FontData* result = fontCache()->getFontData(*font, m_familyIndex, m_fontSelector.get());
+ RefPtr<FontData> result = fontCache()->getFontData(*font, m_familyIndex, m_fontSelector.get());
if (result) {
- m_fontList.append(pair<const FontData*, bool>(result, result->isCustomFont()));
+ m_fontList.append(result);
if (result->isLoading())
m_loadingCustomFonts = true;
}
- return result;
+ return result.get();
}
void FontFallbackList::setPlatformFont(const FontPlatformData& platformData)
{
m_familyIndex = cAllFamiliesScanned;
ASSERT(fontCache()->generation() == m_generation);
- const FontData* fontData = fontCache()->getCachedFontData(&platformData);
- m_fontList.append(pair<const FontData*, bool>(fontData, fontData->isCustomFont()));
+ RefPtr<FontData> fontData = fontCache()->getCachedFontData(&platformData);
+ m_fontList.append(fontData);
}
}
diff --git a/Source/WebCore/platform/graphics/FontFallbackList.h b/Source/WebCore/platform/graphics/FontFallbackList.h
index 12479b2c9..88f1bc796 100644
--- a/Source/WebCore/platform/graphics/FontFallbackList.h
+++ b/Source/WebCore/platform/graphics/FontFallbackList.h
@@ -39,6 +39,7 @@ class FontSelector;
const int cAllFamiliesScanned = -1;
class FontFallbackList : public RefCounted<FontFallbackList> {
+ WTF_MAKE_NONCOPYABLE(FontFallbackList);
public:
static PassRefPtr<FontFallbackList> create() { return adoptRef(new FontFallbackList()); }
@@ -63,10 +64,6 @@ public:
const GlyphPages& glyphPages() const { return m_pages; }
private:
- friend class SVGTextRunRenderingContext;
- void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; }
- void setGlyphPages(const GlyphPages& pages) { m_pages = pages; }
-
FontFallbackList();
const SimpleFontData* primarySimpleFontData(const Font* f)
@@ -83,8 +80,10 @@ private:
void setPlatformFont(const FontPlatformData&);
void releaseFontData();
-
- mutable Vector<pair<const FontData*, bool>, 1> m_fontList;
+ void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; }
+ void setGlyphPages(const GlyphPages& pages) { m_pages = pages; }
+
+ mutable Vector<RefPtr<FontData>, 1> m_fontList;
mutable GlyphPages m_pages;
mutable GlyphPageTreeNode* m_pageZero;
mutable const SimpleFontData* m_cachedPrimarySimpleFontData;
@@ -96,6 +95,7 @@ private:
mutable bool m_loadingCustomFonts : 1;
friend class Font;
+ friend class SVGTextRunRenderingContext;
};
}
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp
index 3ae0ad581..7ed7a9703 100644
--- a/Source/WebCore/platform/graphics/FontFastPath.cpp
+++ b/Source/WebCore/platform/graphics/FontFastPath.cpp
@@ -42,9 +42,38 @@ using namespace std;
namespace WebCore {
-GlyphData Font::glyphDataForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const
+static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCharacterWithTextOrientation(UChar32 character, TextOrientation orientation, GlyphData& data, GlyphPage* page, unsigned pageNumber)
{
- return glyphDataAndPageForCharacter(c, mirror, variant).first;
+ if (orientation == TextOrientationVerticalRight) {
+ RefPtr<SimpleFontData> verticalRightFontData = data.fontData->verticalRightOrientationFontData();
+ GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(verticalRightFontData.get(), pageNumber);
+ GlyphPage* verticalRightPage = verticalRightNode->page();
+ if (verticalRightPage) {
+ GlyphData verticalRightData = verticalRightPage->glyphDataForCharacter(character);
+ // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked
+ // into it.
+ if (data.glyph != verticalRightData.glyph)
+ return make_pair(data, page);
+ // The glyphs are identical, meaning that we should just use the horizontal glyph.
+ if (verticalRightData.fontData)
+ return make_pair(verticalRightData, verticalRightPage);
+ }
+ } else if (orientation == TextOrientationUpright) {
+ RefPtr<SimpleFontData> uprightFontData = data.fontData->uprightOrientationFontData();
+ GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(uprightFontData.get(), pageNumber);
+ GlyphPage* uprightPage = uprightNode->page();
+ if (uprightPage) {
+ GlyphData uprightData = uprightPage->glyphDataForCharacter(character);
+ // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright.
+ if (data.glyph == uprightData.glyph)
+ return make_pair(data, page);
+ // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that
+ // glyph, so we fall back to the upright data and use the horizontal glyph.
+ if (uprightData.fontData)
+ return make_pair(uprightData, uprightPage);
+ }
+ }
+ return make_pair(data, page);
}
std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const
@@ -68,13 +97,13 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
unsigned pageNumber = (c / GlyphPage::size);
- GlyphPageTreeNode* node = pageNumber ? m_fontList->m_pages.get(pageNumber) : m_fontList->m_pageZero;
+ GlyphPageTreeNode* node = pageNumber ? m_fontFallbackList->m_pages.get(pageNumber) : m_fontFallbackList->m_pageZero;
if (!node) {
node = GlyphPageTreeNode::getRootChild(fontDataAt(0), pageNumber);
if (pageNumber)
- m_fontList->m_pages.set(pageNumber, node);
+ m_fontFallbackList->m_pages.set(pageNumber, node);
else
- m_fontList->m_pageZero = node;
+ m_fontFallbackList->m_pageZero = node;
}
GlyphPage* page = 0;
@@ -95,40 +124,9 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
variant = BrokenIdeographVariant;
break;
}
- } else {
- if (m_fontDescription.textOrientation() == TextOrientationVerticalRight) {
- const SimpleFontData* verticalRightFontData = data.fontData->verticalRightOrientationFontData();
- GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(verticalRightFontData, pageNumber);
- GlyphPage* verticalRightPage = verticalRightNode->page();
- if (verticalRightPage) {
- GlyphData verticalRightData = verticalRightPage->glyphDataForCharacter(c);
- // If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked
- // into it.
- if (data.glyph != verticalRightData.glyph)
- return make_pair(data, page);
- // The glyphs are identical, meaning that we should just use the horizontal glyph.
- if (verticalRightData.fontData)
- return make_pair(verticalRightData, verticalRightPage);
- }
- } else if (m_fontDescription.textOrientation() == TextOrientationUpright) {
- const SimpleFontData* uprightFontData = data.fontData->uprightOrientationFontData();
- GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(uprightFontData, pageNumber);
- GlyphPage* uprightPage = uprightNode->page();
- if (uprightPage) {
- GlyphData uprightData = uprightPage->glyphDataForCharacter(c);
- // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright.
- if (data.glyph == uprightData.glyph)
- return make_pair(data, page);
- // The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that
- // glyph, so we fall back to the upright data and use the horizontal glyph.
- if (uprightData.fontData)
- return make_pair(uprightData, uprightPage);
- }
- }
+ } else
+ return glyphDataAndPageForCharacterWithTextOrientation(c, m_fontDescription.textOrientation(), data, page, pageNumber);
- // Shouldn't be possible to even reach this point.
- ASSERT_NOT_REACHED();
- }
return make_pair(data, page);
}
@@ -139,9 +137,9 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
// Proceed with the fallback list.
node = node->getChild(fontDataAt(node->level()), pageNumber);
if (pageNumber)
- m_fontList->m_pages.set(pageNumber, node);
+ m_fontFallbackList->m_pages.set(pageNumber, node);
else
- m_fontList->m_pageZero = node;
+ m_fontFallbackList->m_pageZero = node;
}
}
if (variant != NormalVariant) {
@@ -152,11 +150,11 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
if (data.fontData) {
// The variantFontData function should not normally return 0.
// But if it does, we will just render the capital letter big.
- const SimpleFontData* variantFontData = data.fontData->variantFontData(m_fontDescription, variant);
+ RefPtr<SimpleFontData> variantFontData = data.fontData->variantFontData(m_fontDescription, variant);
if (!variantFontData)
return make_pair(data, page);
- GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData, pageNumber);
+ GlyphPageTreeNode* variantNode = GlyphPageTreeNode::getRootChild(variantFontData.get(), pageNumber);
GlyphPage* variantPage = variantNode->page();
if (variantPage) {
GlyphData data = variantPage->glyphDataForCharacter(c);
@@ -176,9 +174,9 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
// Proceed with the fallback list.
node = node->getChild(fontDataAt(node->level()), pageNumber);
if (pageNumber)
- m_fontList->m_pages.set(pageNumber, node);
+ m_fontFallbackList->m_pages.set(pageNumber, node);
else
- m_fontList->m_pageZero = node;
+ m_fontFallbackList->m_pageZero = node;
}
}
@@ -198,7 +196,7 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
codeUnits[1] = U16_TRAIL(c);
codeUnitsLength = 2;
}
- const SimpleFontData* characterFontData = fontCache()->getFontDataForCharacters(*this, codeUnits, codeUnitsLength);
+ RefPtr<SimpleFontData> characterFontData = fontCache()->getFontDataForCharacters(*this, codeUnits, codeUnitsLength);
if (characterFontData) {
if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && isCJKIdeographOrSymbol(c))
variant = BrokenIdeographVariant;
@@ -207,7 +205,7 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
}
if (characterFontData) {
// Got the fallback glyph and font.
- GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData, pageNumber)->page();
+ GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData.get(), pageNumber)->page();
GlyphData data = fallbackPage && fallbackPage->fontDataForCharacter(c) ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
// Cache it so we don't have to do system fallback again next time.
if (variant == NormalVariant) {
@@ -216,12 +214,14 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
// Also, sometimes we cannot map a font for the character on WINCE, but GDI can still
// display the character, probably because the font package is not installed correctly.
// So we just always set the glyph to be same as the character, and let GDI solve it.
- page->setGlyphDataForCharacter(c, c, characterFontData);
+ page->setGlyphDataForCharacter(c, c, characterFontData.get());
characterFontData->setMaxGlyphPageTreeLevel(max(characterFontData->maxGlyphPageTreeLevel(), node->level()));
return make_pair(page->glyphDataForCharacter(c), page);
#else
page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
data.fontData->setMaxGlyphPageTreeLevel(max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
+ if (!isCJKIdeographOrSymbol(c) && data.fontData->platformData().orientation() != Horizontal && !data.fontData->isTextOrientationFallback())
+ return glyphDataAndPageForCharacterWithTextOrientation(c, m_fontDescription.textOrientation(), data, fallbackPage, pageNumber);
#endif
}
return make_pair(data, page);
@@ -328,7 +328,10 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int
float initialAdvance;
WidthIterator it(this, run, 0, false, forTextEmphasis);
- it.advance(from);
+ // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or
+ // ligatures are enabled.
+ GlyphBuffer localGlyphBuffer;
+ it.advance(from, &localGlyphBuffer);
float beforeWidth = it.m_runWidthSoFar;
it.advance(to, &glyphBuffer);
@@ -339,15 +342,13 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int
if (run.rtl()) {
float finalRoundingWidth = it.m_finalRoundingWidth;
- it.advance(run.length());
+ it.advance(run.length(), &localGlyphBuffer);
initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
} else
initialAdvance = beforeWidth;
- if (run.rtl()) {
- for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
- glyphBuffer.swap(i, end);
- }
+ if (run.rtl())
+ glyphBuffer.reverse(0, glyphBuffer.size());
return initialAdvance;
}
@@ -466,10 +467,11 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const
drawGlyphBuffer(context, run, markBuffer, startPoint);
}
-float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
WidthIterator it(this, run, fallbackFonts, glyphOverflow);
- it.advance(run.length(), glyphBuffer);
+ GlyphBuffer glyphBuffer;
+ it.advance(run.length(), (typesettingFeatures() & (Kerning | Ligatures)) ? &glyphBuffer : 0);
if (glyphOverflow) {
glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
@@ -483,15 +485,16 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
FloatRect Font::selectionRectForSimpleText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
{
+ GlyphBuffer glyphBuffer;
WidthIterator it(this, run);
- it.advance(from);
+ it.advance(from, &glyphBuffer);
float beforeWidth = it.m_runWidthSoFar;
- it.advance(to);
+ it.advance(to, &glyphBuffer);
float afterWidth = it.m_runWidthSoFar;
// Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning.
if (run.rtl()) {
- it.advance(run.length());
+ it.advance(run.length(), &glyphBuffer);
float totalWidth = it.m_runWidthSoFar;
return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
}
@@ -507,11 +510,11 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu
GlyphBuffer localGlyphBuffer;
unsigned offset;
if (run.rtl()) {
- delta -= floatWidthForSimpleText(run, 0);
+ delta -= floatWidthForSimpleText(run);
while (1) {
offset = it.m_currentCharacter;
float w;
- if (!it.advanceOneCharacter(w, &localGlyphBuffer))
+ if (!it.advanceOneCharacter(w, localGlyphBuffer))
break;
delta += w;
if (includePartialGlyphs) {
@@ -526,7 +529,7 @@ int Font::offsetForPositionForSimpleText(const TextRun& run, float x, bool inclu
while (1) {
offset = it.m_currentCharacter;
float w;
- if (!it.advanceOneCharacter(w, &localGlyphBuffer))
+ if (!it.advanceOneCharacter(w, localGlyphBuffer))
break;
delta -= w;
if (includePartialGlyphs) {
diff --git a/Source/WebCore/platform/graphics/FontMetrics.h b/Source/WebCore/platform/graphics/FontMetrics.h
index 11b062918..7981d8eea 100644
--- a/Source/WebCore/platform/graphics/FontMetrics.h
+++ b/Source/WebCore/platform/graphics/FontMetrics.h
@@ -36,6 +36,7 @@ public:
, m_lineGap(0)
, m_lineSpacing(0)
, m_xHeight(0)
+ , m_hasXHeight(false)
{
}
@@ -72,7 +73,14 @@ public:
void setLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; }
float xHeight() const { return m_xHeight; }
- void setXHeight(float xHeight) { m_xHeight = xHeight; }
+ void setXHeight(float xHeight)
+ {
+ m_xHeight = xHeight;
+ m_hasXHeight = true;
+ }
+
+ bool hasXHeight() const { return m_hasXHeight && m_xHeight > 0; }
+ void setHasXHeight(bool hasXHeight) { m_hasXHeight = hasXHeight; }
// Integer variants of certain metrics, used for HTML rendering.
int ascent(FontBaseline baselineType = AlphabeticBaseline) const
@@ -113,6 +121,7 @@ private:
m_lineGap = 0;
m_lineSpacing = 0;
m_xHeight = 0;
+ m_hasXHeight = false;
}
unsigned m_unitsPerEm;
@@ -121,6 +130,7 @@ private:
float m_lineGap;
float m_lineSpacing;
float m_xHeight;
+ bool m_hasXHeight;
};
static inline float scaleEmToUnits(float x, unsigned unitsPerEm)
diff --git a/Source/WebCore/platform/graphics/FontSelector.h b/Source/WebCore/platform/graphics/FontSelector.h
index 2c7d1494e..aaaaae2d4 100644
--- a/Source/WebCore/platform/graphics/FontSelector.h
+++ b/Source/WebCore/platform/graphics/FontSelector.h
@@ -27,6 +27,7 @@
#define FontSelector_h
#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
@@ -38,7 +39,7 @@ class FontSelectorClient;
class FontSelector : public RefCounted<FontSelector> {
public:
virtual ~FontSelector() { }
- virtual FontData* getFontData(const FontDescription&, const AtomicString& familyName) = 0;
+ virtual PassRefPtr<FontData> getFontData(const FontDescription&, const AtomicString& familyName) = 0;
virtual void fontCacheInvalidated() { }
diff --git a/Source/WebCore/platform/graphics/FontWidthVariant.h b/Source/WebCore/platform/graphics/FontWidthVariant.h
index bbc98ee5c..f44329745 100644
--- a/Source/WebCore/platform/graphics/FontWidthVariant.h
+++ b/Source/WebCore/platform/graphics/FontWidthVariant.h
@@ -28,7 +28,17 @@
namespace WebCore {
-enum FontWidthVariant { RegularWidth, HalfWidth, ThirdWidth, QuarterWidth };
+enum FontWidthVariant {
+ RegularWidth,
+ HalfWidth,
+ ThirdWidth,
+ QuarterWidth,
+ LastFontWidthVariant = QuarterWidth
+};
+
+const unsigned FontWidthVariantWidth = 2;
+
+COMPILE_ASSERT(LastFontWidthVariant >> FontWidthVariantWidth == 0, FontWidthVariantWidth_is_correct);
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/GlyphBuffer.h b/Source/WebCore/platform/graphics/GlyphBuffer.h
index 0305ced0f..5feafb140 100644
--- a/Source/WebCore/platform/graphics/GlyphBuffer.h
+++ b/Source/WebCore/platform/graphics/GlyphBuffer.h
@@ -63,11 +63,32 @@ typedef Glyph GlyphBufferGlyph;
// CG uses CGSize instead of FloatSize so that the result of advances()
// can be passed directly to CGContextShowGlyphsWithAdvances in FontMac.mm
#if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
-typedef CGSize GlyphBufferAdvance;
+struct GlyphBufferAdvance : CGSize {
+public:
+ GlyphBufferAdvance(CGSize size) : CGSize(size)
+ {
+ }
+
+ void setWidth(CGFloat width) { this->CGSize::width = width; }
+ CGFloat width() const { return this->CGSize::width; }
+ CGFloat height() const { return this->CGSize::height; }
+};
#elif OS(WINCE)
// There is no cross-platform code that uses the height of GlyphBufferAdvance,
// so we can save memory space on embedded devices by storing only the width
-typedef float GlyphBufferAdvance;
+struct GlyphBufferAdvance {
+public:
+ GlyphBufferAdvance(float width)
+ : advance(width)
+ {
+ }
+
+ void setWidth(float width) { advance = width; }
+ float width() const { return advance; }
+
+private:
+ float advance;
+};
#else
typedef FloatSize GlyphBufferAdvance;
#endif
@@ -94,27 +115,6 @@ public:
const SimpleFontData* fontDataAt(int index) const { return m_fontData[index]; }
- void swap(int index1, int index2)
- {
- const SimpleFontData* f = m_fontData[index1];
- m_fontData[index1] = m_fontData[index2];
- m_fontData[index2] = f;
-
- GlyphBufferGlyph g = m_glyphs[index1];
- m_glyphs[index1] = m_glyphs[index2];
- m_glyphs[index2] = g;
-
- GlyphBufferAdvance s = m_advances[index1];
- m_advances[index1] = m_advances[index2];
- m_advances[index2] = s;
-
-#if PLATFORM(WIN)
- FloatSize offset = m_offsets[index1];
- m_offsets[index1] = m_offsets[index2];
- m_offsets[index2] = offset;
-#endif
- }
-
Glyph glyphAt(int index) const
{
#if USE(CAIRO) || (PLATFORM(WX) && defined(wxUSE_CAIRO) && wxUSE_CAIRO)
@@ -126,13 +126,7 @@ public:
float advanceAt(int index) const
{
-#if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
- return m_advances[index].width;
-#elif OS(WINCE)
- return m_advances[index];
-#else
return m_advances[index].width();
-#endif
}
FloatSize offsetAt(int index) const
@@ -192,20 +186,41 @@ public:
}
#endif
+ void reverse(int from, int length)
+ {
+ for (int i = from, end = from + length - 1; i < end; ++i, --end)
+ swap(i, end);
+ }
+
void expandLastAdvance(float width)
{
ASSERT(!isEmpty());
GlyphBufferAdvance& lastAdvance = m_advances.last();
-#if USE(CG) || (OS(DARWIN) && (PLATFORM(WX) || PLATFORM(CHROMIUM)))
- lastAdvance.width += width;
-#elif OS(WINCE)
- lastAdvance += width;
-#else
- lastAdvance += FloatSize(width, 0);
-#endif
+ lastAdvance.setWidth(lastAdvance.width() + width);
}
private:
+ void swap(int index1, int index2)
+ {
+ const SimpleFontData* f = m_fontData[index1];
+ m_fontData[index1] = m_fontData[index2];
+ m_fontData[index2] = f;
+
+ GlyphBufferGlyph g = m_glyphs[index1];
+ m_glyphs[index1] = m_glyphs[index2];
+ m_glyphs[index2] = g;
+
+ GlyphBufferAdvance s = m_advances[index1];
+ m_advances[index1] = m_advances[index2];
+ m_advances[index2] = s;
+
+#if PLATFORM(WIN)
+ FloatSize offset = m_offsets[index1];
+ m_offsets[index1] = m_offsets[index2];
+ m_offsets[index2] = offset;
+#endif
+ }
+
Vector<const SimpleFontData*, 2048> m_fontData;
Vector<GlyphBufferGlyph, 2048> m_glyphs;
Vector<GlyphBufferAdvance, 2048> m_advances;
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 770ce122d..c11657b3d 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -55,17 +55,17 @@ GlyphPageTreeNode* GlyphPageTreeNode::getRoot(unsigned pageNumber)
pageZeroRoot = new GlyphPageTreeNode;
}
- GlyphPageTreeNode* node = pageNumber ? roots->get(pageNumber) : pageZeroRoot;
- if (!node) {
- node = new GlyphPageTreeNode;
+ if (!pageNumber)
+ return pageZeroRoot;
+
+ if (GlyphPageTreeNode* foundNode = roots->get(pageNumber))
+ return foundNode;
+
+ GlyphPageTreeNode* node = new GlyphPageTreeNode;
#ifndef NDEBUG
- node->m_pageNumber = pageNumber;
+ node->m_pageNumber = pageNumber;
#endif
- if (pageNumber)
- roots->set(pageNumber, node);
- else
- pageZeroRoot = node;
- }
+ roots->set(pageNumber, node);
return node;
}
@@ -75,7 +75,7 @@ size_t GlyphPageTreeNode::treeGlyphPageCount()
if (roots) {
HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end();
for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); it != end; ++it)
- count += it->second->pageCount();
+ count += it->value->pageCount();
}
if (pageZeroRoot)
@@ -87,9 +87,9 @@ size_t GlyphPageTreeNode::treeGlyphPageCount()
size_t GlyphPageTreeNode::pageCount() const
{
size_t count = m_page && m_page->owner() == this ? 1 : 0;
- HashMap<const FontData*, GlyphPageTreeNode*>::const_iterator end = m_children.end();
- for (HashMap<const FontData*, GlyphPageTreeNode*>::const_iterator it = m_children.begin(); it != end; ++it)
- count += it->second->pageCount();
+ GlyphPageTreeNodeMap::const_iterator end = m_children.end();
+ for (GlyphPageTreeNodeMap::const_iterator it = m_children.begin(); it != end; ++it)
+ count += it->value->pageCount();
return count;
}
@@ -100,7 +100,7 @@ void GlyphPageTreeNode::pruneTreeCustomFontData(const FontData* fontData)
if (roots) {
HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end();
for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); it != end; ++it)
- it->second->pruneCustomFontData(fontData);
+ it->value->pruneCustomFontData(fontData);
}
if (pageZeroRoot)
@@ -112,19 +112,13 @@ void GlyphPageTreeNode::pruneTreeFontData(const SimpleFontData* fontData)
if (roots) {
HashMap<int, GlyphPageTreeNode*>::iterator end = roots->end();
for (HashMap<int, GlyphPageTreeNode*>::iterator it = roots->begin(); it != end; ++it)
- it->second->pruneFontData(fontData);
+ it->value->pruneFontData(fontData);
}
if (pageZeroRoot)
pageZeroRoot->pruneFontData(fontData);
}
-GlyphPageTreeNode::~GlyphPageTreeNode()
-{
- deleteAllValues(m_children);
- delete m_systemFallbackChild;
-}
-
static bool fill(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
{
#if ENABLE(SVG_FONTS)
@@ -242,7 +236,7 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
}
zeroFilled = true;
}
- haveGlyphs |= fill(pageToFill, from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData());
+ haveGlyphs |= fill(pageToFill, from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData().get());
if (scratchPage) {
ASSERT(to <= static_cast<int>(GlyphPage::size));
for (int j = from; j < to; j++) {
@@ -323,28 +317,28 @@ GlyphPageTreeNode* GlyphPageTreeNode::getChild(const FontData* fontData, unsigne
ASSERT(fontData || !m_isSystemFallback);
ASSERT(pageNumber == m_pageNumber);
- GlyphPageTreeNode* child = fontData ? m_children.get(fontData) : m_systemFallbackChild;
- if (!child) {
- child = new GlyphPageTreeNode;
- child->m_parent = this;
- child->m_level = m_level + 1;
- if (fontData && fontData->isCustomFont()) {
- for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent)
- curr->m_customFontCount++;
- }
+ if (GlyphPageTreeNode* foundChild = fontData ? m_children.get(fontData) : m_systemFallbackChild.get())
+ return foundChild;
+
+ GlyphPageTreeNode* child = new GlyphPageTreeNode;
+ child->m_parent = this;
+ child->m_level = m_level + 1;
+ if (fontData && fontData->isCustomFont()) {
+ for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent)
+ curr->m_customFontCount++;
+ }
#ifndef NDEBUG
- child->m_pageNumber = m_pageNumber;
+ child->m_pageNumber = m_pageNumber;
#endif
- if (fontData) {
- m_children.set(fontData, child);
- fontData->setMaxGlyphPageTreeLevel(max(fontData->maxGlyphPageTreeLevel(), child->m_level));
- } else {
- m_systemFallbackChild = child;
- child->m_isSystemFallback = true;
- }
- child->initializePage(fontData, pageNumber);
+ if (fontData) {
+ m_children.set(fontData, adoptPtr(child));
+ fontData->setMaxGlyphPageTreeLevel(max(fontData->maxGlyphPageTreeLevel(), child->m_level));
+ } else {
+ m_systemFallbackChild = adoptPtr(child);
+ child->m_isSystemFallback = true;
}
+ child->initializePage(fontData, pageNumber);
return child;
}
@@ -354,41 +348,33 @@ void GlyphPageTreeNode::pruneCustomFontData(const FontData* fontData)
return;
// Prune any branch that contains this FontData.
- GlyphPageTreeNode* node = m_children.get(fontData);
- if (node) {
- m_children.remove(fontData);
- unsigned fontCount = node->m_customFontCount + 1;
- delete node;
- for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent)
- curr->m_customFontCount -= fontCount;
+ if (OwnPtr<GlyphPageTreeNode> node = m_children.take(fontData)) {
+ if (unsigned customFontCount = node->m_customFontCount + 1) {
+ for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent)
+ curr->m_customFontCount -= customFontCount;
+ }
}
// Check any branches that remain that still have custom fonts underneath them.
if (!m_customFontCount)
return;
- HashMap<const FontData*, GlyphPageTreeNode*>::iterator end = m_children.end();
- for (HashMap<const FontData*, GlyphPageTreeNode*>::iterator it = m_children.begin(); it != end; ++it)
- it->second->pruneCustomFontData(fontData);
+
+ GlyphPageTreeNodeMap::iterator end = m_children.end();
+ for (GlyphPageTreeNodeMap::iterator it = m_children.begin(); it != end; ++it)
+ it->value->pruneCustomFontData(fontData);
}
void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned level)
{
ASSERT(fontData);
- if (!fontData)
- return;
// Prune fall back child (if any) of this font.
if (m_systemFallbackChild && m_systemFallbackChild->m_page)
m_systemFallbackChild->m_page->clearForFontData(fontData);
// Prune any branch that contains this FontData.
- HashMap<const FontData*, GlyphPageTreeNode*>::iterator child = m_children.find(fontData);
- if (child != m_children.end()) {
- GlyphPageTreeNode* node = child->second;
- m_children.remove(fontData);
- unsigned customFontCount = node->m_customFontCount;
- delete node;
- if (customFontCount) {
+ if (OwnPtr<GlyphPageTreeNode> node = m_children.take(fontData)) {
+ if (unsigned customFontCount = node->m_customFontCount) {
for (GlyphPageTreeNode* curr = this; curr; curr = curr->m_parent)
curr->m_customFontCount -= customFontCount;
}
@@ -398,9 +384,9 @@ void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned l
if (level > fontData->maxGlyphPageTreeLevel())
return;
- HashMap<const FontData*, GlyphPageTreeNode*>::iterator end = m_children.end();
- for (HashMap<const FontData*, GlyphPageTreeNode*>::iterator it = m_children.begin(); it != end; ++it)
- it->second->pruneFontData(fontData, level);
+ GlyphPageTreeNodeMap::iterator end = m_children.end();
+ for (GlyphPageTreeNodeMap::iterator it = m_children.begin(); it != end; ++it)
+ it->value->pruneFontData(fontData, level);
}
#ifndef NDEBUG
@@ -410,10 +396,10 @@ void GlyphPageTreeNode::pruneFontData(const SimpleFontData* fontData, unsigned l
indent.fill('\t', level());
indent.append(0);
- HashMap<const FontData*, GlyphPageTreeNode*>::iterator end = m_children.end();
- for (HashMap<const FontData*, GlyphPageTreeNode*>::iterator it = m_children.begin(); it != end; ++it) {
- printf("%s\t%p %s\n", indent.data(), it->first, it->first->description().utf8().data());
- it->second->showSubtree();
+ GlyphPageTreeNodeMap::iterator end = m_children.end();
+ for (GlyphPageTreeNodeMap::iterator it = m_children.begin(); it != end; ++it) {
+ printf("%s\t%p %s\n", indent.data(), it->key, it->key->description().utf8().data());
+ it->value->showSubtree();
}
if (m_systemFallbackChild) {
printf("%s\t* fallback\n", indent.data());
@@ -431,8 +417,8 @@ void showGlyphPageTrees()
showGlyphPageTree(0);
HashMap<int, WebCore::GlyphPageTreeNode*>::iterator end = WebCore::GlyphPageTreeNode::roots->end();
for (HashMap<int, WebCore::GlyphPageTreeNode*>::iterator it = WebCore::GlyphPageTreeNode::roots->begin(); it != end; ++it) {
- printf("\nPage %d:\n", it->first);
- showGlyphPageTree(it->first);
+ printf("\nPage %d:\n", it->key);
+ showGlyphPageTree(it->key);
}
}
diff --git a/Source/WebCore/platform/graphics/GlyphPageTreeNode.h b/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
index f8a9eea84..5b50a01fc 100644
--- a/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
+++ b/Source/WebCore/platform/graphics/GlyphPageTreeNode.h
@@ -32,6 +32,7 @@
#include "GlyphPage.h"
#include <string.h>
#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/unicode/Unicode.h>
@@ -69,23 +70,6 @@ class SimpleFontData;
class GlyphPageTreeNode {
WTF_MAKE_FAST_ALLOCATED;
public:
- GlyphPageTreeNode()
- : m_parent(0)
- , m_level(0)
- , m_isSystemFallback(false)
- , m_customFontCount(0)
- , m_systemFallbackChild(0)
-#ifndef NDEBUG
- , m_pageNumber(0)
-#endif
- {
- }
-
- ~GlyphPageTreeNode();
-
- static HashMap<int, GlyphPageTreeNode*>* roots;
- static GlyphPageTreeNode* pageZeroRoot;
-
static GlyphPageTreeNode* getRootChild(const FontData* fontData, unsigned pageNumber)
{
return getRoot(pageNumber)->getChild(fontData, pageNumber);
@@ -113,6 +97,17 @@ public:
size_t pageCount() const;
private:
+ GlyphPageTreeNode()
+ : m_parent(0)
+ , m_level(0)
+ , m_isSystemFallback(false)
+ , m_customFontCount(0)
+#ifndef NDEBUG
+ , m_pageNumber(0)
+#endif
+ {
+ }
+
static GlyphPageTreeNode* getRoot(unsigned pageNumber);
void initializePage(const FontData*, unsigned pageNumber);
@@ -120,17 +115,23 @@ private:
void showSubtree();
#endif
+ static HashMap<int, GlyphPageTreeNode*>* roots;
+ static GlyphPageTreeNode* pageZeroRoot;
+
+ typedef HashMap<const FontData*, OwnPtr<GlyphPageTreeNode> > GlyphPageTreeNodeMap;
+
+ GlyphPageTreeNodeMap m_children;
GlyphPageTreeNode* m_parent;
RefPtr<GlyphPage> m_page;
unsigned m_level : 31;
bool m_isSystemFallback : 1;
unsigned m_customFontCount;
- HashMap<const FontData*, GlyphPageTreeNode*> m_children;
- GlyphPageTreeNode* m_systemFallbackChild;
+ OwnPtr<GlyphPageTreeNode> m_systemFallbackChild;
#ifndef NDEBUG
unsigned m_pageNumber;
+ friend void ::showGlyphPageTrees();
friend void ::showGlyphPageTree(unsigned pageNumber);
#endif
};
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index 16947fb32..d4a8c1f69 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -499,7 +499,7 @@ namespace WebCore {
#endif
#if PLATFORM(QT)
- void pushTransparencyLayerInternal(const QRect&, qreal, QImage&);
+ void pushTransparencyLayerInternal(const QRect&, qreal, QPixmap&);
void takeOwnershipOfPlatformContext();
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h
index 42076ff78..99a21a2d4 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h
@@ -27,8 +27,8 @@
#define GraphicsContext3D_h
#include "IntRect.h"
-#include "GraphicsLayer.h"
#include "GraphicsTypes3D.h"
+#include "PlatformLayer.h"
#include <wtf/HashMap.h>
#include <wtf/ListHashSet.h>
#include <wtf/Noncopyable.h>
@@ -395,6 +395,7 @@ public:
STENCIL_INDEX8 = 0x8D48,
DEPTH_STENCIL = 0x84F9,
UNSIGNED_INT_24_8 = 0x84FA,
+ DEPTH24_STENCIL8 = 0x88F0,
RENDERBUFFER_WIDTH = 0x8D42,
RENDERBUFFER_HEIGHT = 0x8D43,
RENDERBUFFER_INTERNAL_FORMAT = 0x8D44,
@@ -964,21 +965,65 @@ public:
#endif
#if PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(BLACKBERRY)
+ struct SymbolInfo {
+ SymbolInfo()
+ : type(0)
+ , size(0)
+ {
+ }
+
+ SymbolInfo(GC3Denum type, int size, const String& mappedName)
+ : type(type)
+ , size(size)
+ , mappedName(mappedName)
+ {
+ }
+
+ bool operator==(SymbolInfo& other) const
+ {
+ return type == other.type && size == other.size && mappedName == other.mappedName;
+ }
+
+ GC3Denum type;
+ int size;
+ String mappedName;
+ };
+
+ typedef HashMap<String, SymbolInfo> ShaderSymbolMap;
+
struct ShaderSourceEntry {
+ GC3Denum type;
String source;
+ String translatedSource;
String log;
bool isValid;
+ ShaderSymbolMap attributeMap;
+ ShaderSymbolMap uniformMap;
ShaderSourceEntry()
- : isValid(0)
+ : type(VERTEX_SHADER)
+ , isValid(false)
{
}
+
+ ShaderSymbolMap& symbolMap(ANGLEShaderSymbolType symbolType)
+ {
+ ASSERT(symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE || symbolType == SHADER_SYMBOL_TYPE_UNIFORM);
+ if (symbolType == SHADER_SYMBOL_TYPE_ATTRIBUTE)
+ return attributeMap;
+ return uniformMap;
+ }
};
- HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
+
+ typedef HashMap<Platform3DObject, ShaderSourceEntry> ShaderSourceMap;
+ ShaderSourceMap m_shaderSourceMap;
+
+ String mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
+ String originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType, const String& name);
ANGLEWebKitBridge m_compiler;
#endif
-#if PLATFORM(BLACKBERRY) || (PLATFORM(QT) && defined(QT_OPENGL_ES_2))
+#if PLATFORM(BLACKBERRY) || (PLATFORM(QT) && defined(QT_OPENGL_ES_2)) || (PLATFORM(GTK) && USE(OPENGL_ES_2))
friend class Extensions3DOpenGLES;
OwnPtr<Extensions3DOpenGLES> m_extensions;
#elif !PLATFORM(CHROMIUM)
@@ -1027,7 +1072,6 @@ public:
friend class GraphicsContext3DPrivate;
OwnPtr<GraphicsContext3DPrivate> m_private;
#endif
- bool systemAllowsMultisamplingOnATICards() const;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.cpp b/Source/WebCore/platform/graphics/GraphicsLayer.cpp
index 2ae3fe787..3a32b5145 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -80,7 +80,6 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
, m_acceleratesDrawing(false)
, m_maintainsPixelAlignment(false)
, m_appliesPageScale(false)
- , m_usingTileCache(false)
, m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(0)
@@ -339,21 +338,39 @@ void GraphicsLayer::resumeAnimations()
{
}
-void GraphicsLayer::updateDebugIndicators()
+void GraphicsLayer::getDebugBorderInfo(Color& color, float& width) const
{
- if (GraphicsLayer::showDebugBorders()) {
- if (drawsContent()) {
- if (m_usingTileCache) // tile cache layer: dark blue
- setDebugBorder(Color(0, 0, 128, 128), 0.5);
- else if (m_usingTiledLayer)
- setDebugBorder(Color(255, 128, 0, 128), 2); // tiled layer: orange
- else
- setDebugBorder(Color(0, 128, 32, 128), 2); // normal layer: green
- } else if (masksToBounds()) {
- setDebugBorder(Color(128, 255, 255, 48), 20); // masking layer: pale blue
- } else
- setDebugBorder(Color(255, 255, 0, 192), 2); // container: yellow
+ if (drawsContent()) {
+ if (m_usingTiledLayer) {
+ color = Color(255, 128, 0, 128); // tiled layer: orange
+ width = 2;
+ return;
+ }
+
+ color = Color(0, 128, 32, 128); // normal layer: green
+ width = 2;
+ return;
+ }
+
+ if (masksToBounds()) {
+ color = Color(128, 255, 255, 48); // masking layer: pale blue
+ width = 20;
+ return;
}
+
+ color = Color(255, 255, 0, 192); // container: yellow
+ width = 2;
+}
+
+void GraphicsLayer::updateDebugIndicators()
+{
+ if (!GraphicsLayer::showDebugBorders())
+ return;
+
+ Color borderColor;
+ float width = 0;
+ getDebugBorderInfo(borderColor, width);
+ setDebugBorder(borderColor, width);
}
void GraphicsLayer::setZPosition(float position)
@@ -387,9 +404,9 @@ void GraphicsLayer::distributeOpacity(float accumulatedOpacity)
}
#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
-GraphicsLayer::GraphicsLayerFactory* GraphicsLayer::s_graphicsLayerFactory = 0;
+GraphicsLayer::GraphicsLayerFactoryCallback* GraphicsLayer::s_graphicsLayerFactory = 0;
-void GraphicsLayer::setGraphicsLayerFactory(GraphicsLayer::GraphicsLayerFactory factory)
+void GraphicsLayer::setGraphicsLayerFactory(GraphicsLayer::GraphicsLayerFactoryCallback factory)
{
s_graphicsLayerFactory = factory;
}
@@ -519,7 +536,7 @@ double GraphicsLayer::backingStoreMemoryEstimate() const
return static_cast<double>(4 * size().width()) * size().height();
}
-static void writeIndent(TextStream& ts, int indent)
+void GraphicsLayer::writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
ts << " ";
@@ -645,6 +662,8 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
ts << ")\n";
}
+ dumpAdditionalProperties(ts, indent, behavior);
+
if (m_children.size()) {
writeIndent(ts, indent + 1);
ts << "(children " << m_children.size() << "\n";
@@ -673,7 +692,7 @@ void showGraphicsLayerTree(const WebCore::GraphicsLayer* layer)
if (!layer)
return;
- WTF::String output = layer->layerTreeAsText(LayerTreeAsTextDebug);
+ String output = layer->layerTreeAsText(LayerTreeAsTextDebug | LayerTreeAsTextIncludeVisibleRects);
fprintf(stderr, "%s\n", output.utf8().data());
}
#endif
diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.h b/Source/WebCore/platform/graphics/GraphicsLayer.h
index 37ea8d052..e67a17eae 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayer.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayer.h
@@ -47,6 +47,7 @@
enum LayerTreeAsTextBehaviorFlags {
LayerTreeAsTextBehaviorNormal = 0,
LayerTreeAsTextDebug = 1 << 0, // Dump extra debugging info like layer addresses.
+ LayerTreeAsTextIncludeVisibleRects = 1 << 1,
};
typedef unsigned LayerTreeAsTextBehavior;
@@ -54,6 +55,7 @@ namespace WebCore {
class FloatPoint3D;
class GraphicsContext;
+class GraphicsLayerFactory;
class Image;
class TextStream;
class TiledBacking;
@@ -191,6 +193,9 @@ protected:
class GraphicsLayer {
WTF_MAKE_NONCOPYABLE(GraphicsLayer); WTF_MAKE_FAST_ALLOCATED;
public:
+ static PassOwnPtr<GraphicsLayer> create(GraphicsLayerFactory*, GraphicsLayerClient*);
+
+ // FIXME: Replace all uses of this create function with the one that takes a GraphicsLayerFactory.
static PassOwnPtr<GraphicsLayer> create(GraphicsLayerClient*);
virtual ~GraphicsLayer();
@@ -241,6 +246,9 @@ public:
// The position of the layer (the location of its top-left corner in its parent)
const FloatPoint& position() const { return m_position; }
virtual void setPosition(const FloatPoint& p) { m_position = p; }
+
+ // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
+ virtual void syncPosition(const FloatPoint& p) { m_position = p; }
// Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point
// affects the origin of the transforms.
@@ -381,8 +389,8 @@ public:
// Some compositing systems may do internal batching to synchronize compositing updates
// with updates drawn into the window. These methods flush internal batched state on this layer
// and descendant layers, and this layer only.
- virtual void syncCompositingState(const FloatRect& /* clipRect */) { }
- virtual void syncCompositingStateForThisLayerOnly() { }
+ virtual void flushCompositingState(const FloatRect& /* clipRect */) { }
+ virtual void flushCompositingStateForThisLayerOnly() { }
// Return a string with a human readable form of the layer tree, If debug is true
// pointers for the layers and timing data will be included in the returned string.
@@ -398,8 +406,8 @@ public:
#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
// This allows several alternative GraphicsLayer implementations in the same port,
// e.g. if a different GraphicsLayer implementation is needed in WebKit1 vs. WebKit2.
- typedef PassOwnPtr<GraphicsLayer> GraphicsLayerFactory(GraphicsLayerClient*);
- static void setGraphicsLayerFactory(GraphicsLayerFactory);
+ typedef PassOwnPtr<GraphicsLayer> GraphicsLayerFactoryCallback(GraphicsLayerClient*);
+ static void setGraphicsLayerFactory(GraphicsLayerFactoryCallback);
#endif
protected:
@@ -431,7 +439,12 @@ protected:
GraphicsLayer(GraphicsLayerClient*);
+ static void writeIndent(TextStream&, int indent);
+
void dumpProperties(TextStream&, int indent, LayerTreeAsTextBehavior) const;
+ virtual void dumpAdditionalProperties(TextStream&, int /*indent*/, LayerTreeAsTextBehavior) const { }
+
+ virtual void getDebugBorderInfo(Color&, float& width) const;
GraphicsLayerClient* m_client;
String m_name;
@@ -467,7 +480,6 @@ protected:
bool m_acceleratesDrawing : 1;
bool m_maintainsPixelAlignment : 1;
bool m_appliesPageScale : 1; // Set for the layer which has the page scale applied to it.
- bool m_usingTileCache : 1;
GraphicsLayerPaintingPhase m_paintingPhase;
CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
@@ -487,7 +499,7 @@ protected:
int m_repaintCount;
#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
- static GraphicsLayer::GraphicsLayerFactory* s_graphicsLayerFactory;
+ static GraphicsLayer::GraphicsLayerFactoryCallback* s_graphicsLayerFactory;
#endif
};
diff --git a/Source/WebCore/platform/graphics/GraphicsLayerClient.h b/Source/WebCore/platform/graphics/GraphicsLayerClient.h
index 10b116d9d..7efee0e65 100644
--- a/Source/WebCore/platform/graphics/GraphicsLayerClient.h
+++ b/Source/WebCore/platform/graphics/GraphicsLayerClient.h
@@ -58,14 +58,13 @@ public:
virtual ~GraphicsLayerClient() {}
virtual bool shouldUseTileCache(const GraphicsLayer*) const { return false; }
- virtual bool usingTileCache(const GraphicsLayer*) const { return false; }
// Callback for when hardware-accelerated animation started.
virtual void notifyAnimationStarted(const GraphicsLayer*, double time) = 0;
- // Notification that a layer property changed that requires a subsequent call to syncCompositingState()
+ // Notification that a layer property changed that requires a subsequent call to flushCompositingState()
// to appear on the screen.
- virtual void notifySyncRequired(const GraphicsLayer*) = 0;
+ virtual void notifyFlushRequired(const GraphicsLayer*) = 0;
virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip) = 0;
virtual void didCommitChangesForLayer(const GraphicsLayer*) const { }
diff --git a/Source/WebCore/platform/graphics/GraphicsLayerFactory.h b/Source/WebCore/platform/graphics/GraphicsLayerFactory.h
new file mode 100644
index 000000000..c747bb8a6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/GraphicsLayerFactory.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayerFactory_h
+#define GraphicsLayerFactory_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class GraphicsLayer;
+class GraphicsLayerClient;
+
+class GraphicsLayerFactory {
+public:
+ virtual ~GraphicsLayerFactory() { }
+
+ virtual PassOwnPtr<GraphicsLayer> createGraphicsLayer(GraphicsLayerClient*) = 0;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsLayerFactory_h
diff --git a/Source/WebCore/platform/graphics/Image.h b/Source/WebCore/platform/graphics/Image.h
index feb6e2bc3..5e700c132 100644
--- a/Source/WebCore/platform/graphics/Image.h
+++ b/Source/WebCore/platform/graphics/Image.h
@@ -53,6 +53,10 @@ typedef SIZE* LPSIZE;
typedef struct HBITMAP__ *HBITMAP;
#endif
+#if PLATFORM(QT)
+#include <QPixmap>
+#endif
+
#if PLATFORM(GTK)
typedef struct _GdkPixbuf GdkPixbuf;
#endif
@@ -154,7 +158,7 @@ public:
#endif
#if PLATFORM(QT)
- static void setPlatformResource(const char* name, const QImage&);
+ static void setPlatformResource(const char* name, const QPixmap&);
#endif
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.cpp b/Source/WebCore/platform/graphics/ImageBuffer.cpp
index 46f2d14cd..138d078cf 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/ImageBuffer.cpp
@@ -28,6 +28,7 @@
#include "ImageBuffer.h"
#include "IntRect.h"
+#include "PlatformMemoryInstrumentation.h"
#include <wtf/MathExtras.h>
namespace WebCore {
@@ -112,4 +113,11 @@ bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D&, Platform3DObject, GC
}
#endif
+void ImageBuffer::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image);
+ info.addMember(m_data);
+ info.addMember(m_context);
+}
+
}
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index 06ac56757..fe0aee0f6 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -121,6 +121,8 @@ namespace WebCore {
bool copyToPlatformTexture(GraphicsContext3D&, Platform3DObject, GC3Denum, bool, bool);
+ void reportMemoryUsage(MemoryObjectInfo*) const;
+
private:
#if USE(CG)
NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const;
diff --git a/Source/WebCore/platform/graphics/IntPoint.h b/Source/WebCore/platform/graphics/IntPoint.h
index 0af6e8570..0dd1daab1 100644
--- a/Source/WebCore/platform/graphics/IntPoint.h
+++ b/Source/WebCore/platform/graphics/IntPoint.h
@@ -29,10 +29,6 @@
#include "IntSize.h"
#include <wtf/MathExtras.h>
-#if PLATFORM(QT)
-#include <QDataStream>
-#endif
-
#if USE(CG) || USE(SKIA_ON_MAC_CHROMIUM)
typedef struct CGPoint CGPoint;
#endif
@@ -229,23 +225,6 @@ inline int IntPoint::distanceSquaredToPoint(const IntPoint& point) const
return ((*this) - point).diagonalLengthSquared();
}
-#if PLATFORM(QT)
-inline QDataStream& operator<<(QDataStream& stream, const IntPoint& point)
-{
- stream << point.x() << point.y();
- return stream;
-}
-
-inline QDataStream& operator>>(QDataStream& stream, IntPoint& point)
-{
- int x, y;
- stream >> x >> y;
- point.setX(x);
- point.setY(y);
- return stream;
-}
-#endif
-
} // namespace WebCore
#endif // IntPoint_h
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp
index 47834d5ab..377e8dc7a 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp
@@ -360,7 +360,7 @@ bool MediaPlayer::load(const KURL& url, const ContentType& contentType, const St
// If the MIME type is missing or is not meaningful, try to figure it out from the URL.
if (m_contentMIMEType.isEmpty() || m_contentMIMEType == applicationOctetStream() || m_contentMIMEType == textPlain()) {
- if (protocolIs(m_url.string(), "data"))
+ if (m_url.protocolIsData())
m_contentMIMEType = mimeTypeFromDataURL(m_url.string());
else {
String lastPathComponent = url.lastPathComponent();
@@ -1078,10 +1078,11 @@ void MediaPlayer::keyMessage(const String& keySystem, const String& sessionId, c
m_mediaPlayerClient->mediaPlayerKeyMessage(this, keySystem, sessionId, message, messageLength);
}
-void MediaPlayer::keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
+bool MediaPlayer::keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
{
if (m_mediaPlayerClient)
- m_mediaPlayerClient->mediaPlayerKeyNeeded(this, keySystem, sessionId, initData, initDataLength);
+ return m_mediaPlayerClient->mediaPlayerKeyNeeded(this, keySystem, sessionId, initData, initDataLength);
+ return false;
}
#endif
diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h
index 60876e638..be93e8701 100644
--- a/Source/WebCore/platform/graphics/MediaPlayer.h
+++ b/Source/WebCore/platform/graphics/MediaPlayer.h
@@ -44,7 +44,7 @@
#include <wtf/text/StringHash.h>
#if USE(ACCELERATED_COMPOSITING)
-#include "GraphicsLayer.h"
+#include "PlatformLayer.h"
#endif
OBJC_CLASS AVPlayer;
@@ -184,10 +184,10 @@ public:
#if ENABLE(ENCRYPTED_MEDIA)
enum MediaKeyErrorCode { UnknownError = 1, ClientError, ServiceError, OutputError, HardwareChangeError, DomainError };
- virtual void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) { }
- virtual void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaKeyErrorCode errorCode, unsigned short systemCode) { }
- virtual void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength) { }
- virtual void mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) { }
+ virtual void mediaPlayerKeyAdded(MediaPlayer*, const String&, const String&) { }
+ virtual void mediaPlayerKeyError(MediaPlayer*, const String&, const String&, MediaKeyErrorCode, unsigned short) { }
+ virtual void mediaPlayerKeyMessage(MediaPlayer*, const String&, const String&, const unsigned char*, unsigned) { }
+ virtual bool mediaPlayerKeyNeeded(MediaPlayer*, const String&, const String&, const unsigned char*, unsigned) { return false; }
#endif
virtual String mediaPlayerReferrer() const { return String(); }
@@ -412,7 +412,7 @@ public:
void keyAdded(const String& keySystem, const String& sessionId);
void keyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode);
void keyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength);
- void keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength);
+ bool keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength);
#endif
String referrer() const;
diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
index 87851e44c..c81642f27 100644
--- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -179,9 +179,9 @@ public:
#endif
#if ENABLE(ENCRYPTED_MEDIA)
- virtual MediaPlayer::MediaKeyException addKey(const String& keySystem, const unsigned char* key, unsigned keyLength, const unsigned char* initData, unsigned initDataLength, const String& sessionId) { return MediaPlayer::KeySystemNotSupported; }
- virtual MediaPlayer::MediaKeyException generateKeyRequest(const String& keySystem, const unsigned char* initData, unsigned initDataLength) { return MediaPlayer::KeySystemNotSupported; }
- virtual MediaPlayer::MediaKeyException cancelKeyRequest(const String& keySystem, const String& sessionId) { return MediaPlayer::KeySystemNotSupported; }
+ virtual MediaPlayer::MediaKeyException addKey(const String&, const unsigned char*, unsigned, const unsigned char*, unsigned, const String&) { return MediaPlayer::KeySystemNotSupported; }
+ virtual MediaPlayer::MediaKeyException generateKeyRequest(const String&, const unsigned char*, unsigned) { return MediaPlayer::KeySystemNotSupported; }
+ virtual MediaPlayer::MediaKeyException cancelKeyRequest(const String&, const String&) { return MediaPlayer::KeySystemNotSupported; }
#endif
};
diff --git a/Source/WebCore/platform/graphics/NativeImagePtr.h b/Source/WebCore/platform/graphics/NativeImagePtr.h
index 1fc3fa6c9..c98f8c25a 100644
--- a/Source/WebCore/platform/graphics/NativeImagePtr.h
+++ b/Source/WebCore/platform/graphics/NativeImagePtr.h
@@ -36,7 +36,7 @@ typedef struct CGImage* CGImageRef;
#elif PLATFORM(QT)
#include <qglobal.h>
QT_BEGIN_NAMESPACE
-class QImage;
+class QPixmap;
QT_END_NAMESPACE
#elif USE(CAIRO)
#include "NativeImageCairo.h"
@@ -48,12 +48,16 @@ class NativeImageSkia;
#include "SharedBitmap.h"
#endif
+namespace WTF {
+class MemoryObjectInfo;
+}
+
namespace WebCore {
#if USE(CG)
typedef CGImageRef NativeImagePtr;
#elif PLATFORM(QT)
-typedef QImage* NativeImagePtr;
+typedef QPixmap* NativeImagePtr;
#elif PLATFORM(OPENVG)
class TiledImageOpenVG;
typedef TiledImageOpenVG* NativeImagePtr;
@@ -67,6 +71,7 @@ typedef wxBitmap* NativeImagePtr;
typedef WebCore::NativeImageCairo* NativeImagePtr;
#elif USE(SKIA)
typedef WebCore::NativeImageSkia* NativeImagePtr;
+void reportMemoryUsage(const NativeImageSkia* const&, WTF::MemoryObjectInfo*);
#elif OS(WINCE)
typedef RefPtr<SharedBitmap> NativeImagePtr;
#elif PLATFORM(BLACKBERRY)
diff --git a/Source/WebCore/platform/graphics/OpenGLESShims.h b/Source/WebCore/platform/graphics/OpenGLESShims.h
index 40187004a..bcaf855ea 100644
--- a/Source/WebCore/platform/graphics/OpenGLESShims.h
+++ b/Source/WebCore/platform/graphics/OpenGLESShims.h
@@ -26,7 +26,7 @@
#ifndef OpenGLESShims_h
#define OpenGLESShims_h
-#if PLATFORM(BLACKBERRY) || PLATFORM(QT)
+#if PLATFORM(BLACKBERRY) || PLATFORM(QT) || PLATFORM(GTK)
#define glBindFramebufferEXT glBindFramebuffer
#define glFramebufferTexture2DEXT glFramebufferTexture2D
#define glBindRenderbufferEXT glBindRenderbuffer
diff --git a/Source/WebCore/platform/graphics/Path.cpp b/Source/WebCore/platform/graphics/Path.cpp
index 97960f4b6..f2570ffb5 100644
--- a/Source/WebCore/platform/graphics/Path.cpp
+++ b/Source/WebCore/platform/graphics/Path.cpp
@@ -184,7 +184,7 @@ void Path::addBeziersForRoundedRect(const FloatRect& rect, const FloatSize& topL
closeSubpath();
}
-#if !USE(CG)
+#if !USE(CG) && !PLATFORM(QT)
FloatRect Path::fastBoundingRect() const
{
return boundingRect();
diff --git a/Source/WebCore/platform/graphics/SegmentedFontData.cpp b/Source/WebCore/platform/graphics/SegmentedFontData.cpp
index fd9094baa..efb20a8c1 100644
--- a/Source/WebCore/platform/graphics/SegmentedFontData.cpp
+++ b/Source/WebCore/platform/graphics/SegmentedFontData.cpp
@@ -34,6 +34,7 @@ namespace WebCore {
SegmentedFontData::~SegmentedFontData()
{
+ GlyphPageTreeNode::pruneTreeCustomFontData(this);
}
const SimpleFontData* SegmentedFontData::fontDataForCharacter(UChar32 c) const
@@ -41,9 +42,9 @@ const SimpleFontData* SegmentedFontData::fontDataForCharacter(UChar32 c) const
Vector<FontDataRange>::const_iterator end = m_ranges.end();
for (Vector<FontDataRange>::const_iterator it = m_ranges.begin(); it != end; ++it) {
if (it->from() <= c && it->to() >= c)
- return it->fontData();
+ return it->fontData().get();
}
- return m_ranges[0].fontData();
+ return m_ranges[0].fontData().get();
}
bool SegmentedFontData::containsCharacter(UChar32 c) const
diff --git a/Source/WebCore/platform/graphics/SegmentedFontData.h b/Source/WebCore/platform/graphics/SegmentedFontData.h
index 645dc0d5f..45d7d158c 100644
--- a/Source/WebCore/platform/graphics/SegmentedFontData.h
+++ b/Source/WebCore/platform/graphics/SegmentedFontData.h
@@ -34,7 +34,7 @@ namespace WebCore {
class SimpleFontData;
struct FontDataRange {
- FontDataRange(UChar32 from, UChar32 to, const SimpleFontData* fontData)
+ FontDataRange(UChar32 from, UChar32 to, PassRefPtr<SimpleFontData> fontData)
: m_from(from)
, m_to(to)
, m_fontData(fontData)
@@ -43,16 +43,18 @@ struct FontDataRange {
UChar32 from() const { return m_from; }
UChar32 to() const { return m_to; }
- const SimpleFontData* fontData() const { return m_fontData; }
+ PassRefPtr<SimpleFontData> fontData() const { return m_fontData; }
private:
UChar32 m_from;
UChar32 m_to;
- const SimpleFontData* m_fontData;
+ RefPtr<SimpleFontData> m_fontData;
};
class SegmentedFontData : public FontData {
public:
+ static PassRefPtr<SegmentedFontData> create() { return adoptRef(new SegmentedFontData); }
+
virtual ~SegmentedFontData();
void appendRange(const FontDataRange& range) { m_ranges.append(range); }
@@ -64,6 +66,8 @@ public:
#endif
private:
+ SegmentedFontData() { }
+
virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
virtual bool containsCharacters(const UChar*, int length) const;
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp
index eae95bdcb..28fa5ab15 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp
@@ -150,7 +150,9 @@ SimpleFontData::~SimpleFontData()
#endif
platformDestroy();
- if (!isCustomFont())
+ if (isCustomFont())
+ GlyphPageTreeNode::pruneTreeCustomFontData(this);
+ else
GlyphPageTreeNode::pruneTreeFontData(this);
}
@@ -170,36 +172,36 @@ bool SimpleFontData::isSegmented() const
return false;
}
-SimpleFontData* SimpleFontData::verticalRightOrientationFontData() const
+PassRefPtr<SimpleFontData> SimpleFontData::verticalRightOrientationFontData() const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->verticalRightOrientation) {
FontPlatformData verticalRightPlatformData(m_platformData);
verticalRightPlatformData.setOrientation(Horizontal);
- m_derivedFontData->verticalRightOrientation = adoptPtr(new SimpleFontData(verticalRightPlatformData, isCustomFont(), false, true));
+ m_derivedFontData->verticalRightOrientation = create(verticalRightPlatformData, isCustomFont(), false, true);
}
- return m_derivedFontData->verticalRightOrientation.get();
+ return m_derivedFontData->verticalRightOrientation;
}
-SimpleFontData* SimpleFontData::uprightOrientationFontData() const
+PassRefPtr<SimpleFontData> SimpleFontData::uprightOrientationFontData() const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->uprightOrientation)
- m_derivedFontData->uprightOrientation = adoptPtr(new SimpleFontData(m_platformData, isCustomFont(), false, true));
- return m_derivedFontData->uprightOrientation.get();
+ m_derivedFontData->uprightOrientation = create(m_platformData, isCustomFont(), false, true);
+ return m_derivedFontData->uprightOrientation;
}
-SimpleFontData* SimpleFontData::brokenIdeographFontData() const
+PassRefPtr<SimpleFontData> SimpleFontData::brokenIdeographFontData() const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->brokenIdeograph) {
- m_derivedFontData->brokenIdeograph = adoptPtr(new SimpleFontData(m_platformData, isCustomFont(), false));
+ m_derivedFontData->brokenIdeograph = create(m_platformData, isCustomFont(), false);
m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFallback = true;
}
- return m_derivedFontData->brokenIdeograph.get();
+ return m_derivedFontData->brokenIdeograph;
}
#ifndef NDEBUG
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h
index 66208837c..db28040fc 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.h
+++ b/Source/WebCore/platform/graphics/SimpleFontData.h
@@ -29,6 +29,7 @@
#include "FontMetrics.h"
#include "FontPlatformData.h"
#include "FloatRect.h"
+#include "GlyphBuffer.h"
#include "GlyphMetricsMap.h"
#include "GlyphPageTreeNode.h"
#if ENABLE(OPENTYPE_VERTICAL)
@@ -37,8 +38,13 @@
#include "TypesettingFeatures.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/UnusedParam.h>
#include <wtf/text/StringHash.h>
+#if PLATFORM(MAC)
+#include "WebCoreSystemInterface.h"
+#endif
+
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
#include <wtf/RetainPtr.h>
#endif
@@ -79,10 +85,16 @@ public:
};
// Used to create platform fonts.
- SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
+ static PassRefPtr<SimpleFontData> create(const FontPlatformData& platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false)
+ {
+ return adoptRef(new SimpleFontData(platformData, isCustomFont, isLoading, isTextOrientationFallback));
+ }
// Used to create SVG Fonts.
- SimpleFontData(PassOwnPtr<AdditionalFontData>, float fontSize, bool syntheticBold, bool syntheticItalic);
+ static PassRefPtr<SimpleFontData> create(PassOwnPtr<AdditionalFontData> fontData, float fontSize, bool syntheticBold, bool syntheticItalic)
+ {
+ return adoptRef(new SimpleFontData(fontData, fontSize, syntheticBold, syntheticItalic));
+ }
virtual ~SimpleFontData();
@@ -91,11 +103,11 @@ public:
const OpenTypeVerticalData* verticalData() const { return m_verticalData; }
#endif
- SimpleFontData* smallCapsFontData(const FontDescription&) const;
- SimpleFontData* emphasisMarkFontData(const FontDescription&) const;
- SimpleFontData* brokenIdeographFontData() const;
+ PassRefPtr<SimpleFontData> smallCapsFontData(const FontDescription&) const;
+ PassRefPtr<SimpleFontData> emphasisMarkFontData(const FontDescription&) const;
+ PassRefPtr<SimpleFontData> brokenIdeographFontData() const;
- SimpleFontData* variantFontData(const FontDescription& description, FontDataVariant variant) const
+ PassRefPtr<SimpleFontData> variantFontData(const FontDescription& description, FontDataVariant variant) const
{
switch (variant) {
case SmallCapsVariant:
@@ -112,8 +124,8 @@ public:
return const_cast<SimpleFontData*>(this);
}
- SimpleFontData* verticalRightOrientationFontData() const;
- SimpleFontData* uprightOrientationFontData() const;
+ PassRefPtr<SimpleFontData> verticalRightOrientationFontData() const;
+ PassRefPtr<SimpleFontData> uprightOrientationFontData() const;
bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
@@ -178,9 +190,27 @@ public:
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
+#endif
+
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) || USE(HARFBUZZ_NG)
bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
#endif
+ bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const
+ {
+#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+ UNUSED_PARAM(glyphs);
+ UNUSED_PARAM(advances);
+ UNUSED_PARAM(glyphCount);
+ UNUSED_PARAM(typesettingFeatures);
+ ASSERT_NOT_REACHED();
+ return false;
+#else
+ wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0);
+ return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options);
+#endif
+ }
+
#if PLATFORM(QT)
QRawFont getQtRawFont() const { return m_platformData.rawFont(); }
#endif
@@ -201,6 +231,10 @@ public:
#endif
private:
+ SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
+
+ SimpleFontData(PassOwnPtr<AdditionalFontData> , float fontSize, bool syntheticBold, bool syntheticItalic);
+
void platformInit();
void platformGlyphInit();
void platformCharWidthInit();
@@ -210,7 +244,7 @@ private:
void commonInit();
- PassOwnPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const;
+ PassRefPtr<SimpleFontData> createScaledFontData(const FontDescription&, float scaleFactor) const;
#if (PLATFORM(WIN) && !OS(WINCE)) \
|| (OS(WINDOWS) && PLATFORM(WX))
@@ -254,11 +288,11 @@ private:
~DerivedFontData();
bool forCustomFont;
- OwnPtr<SimpleFontData> smallCaps;
- OwnPtr<SimpleFontData> emphasisMark;
- OwnPtr<SimpleFontData> brokenIdeograph;
- OwnPtr<SimpleFontData> verticalRightOrientation;
- OwnPtr<SimpleFontData> uprightOrientation;
+ RefPtr<SimpleFontData> smallCaps;
+ RefPtr<SimpleFontData> emphasisMark;
+ RefPtr<SimpleFontData> brokenIdeograph;
+ RefPtr<SimpleFontData> verticalRightOrientation;
+ RefPtr<SimpleFontData> uprightOrientation;
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
mutable RetainPtr<CFMutableDictionaryRef> compositeFontReferences;
#endif
@@ -278,6 +312,9 @@ private:
#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN))
mutable HashMap<unsigned, RetainPtr<CFDictionaryRef> > m_CFStringAttributes;
+#endif
+
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) || USE(HARFBUZZ_NG)
mutable OwnPtr<HashMap<String, bool> > m_combiningCharacterSequenceSupport;
#endif
diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h
index 8762d436e..c64f098fe 100644
--- a/Source/WebCore/platform/graphics/TextRun.h
+++ b/Source/WebCore/platform/graphics/TextRun.h
@@ -59,7 +59,7 @@ public:
typedef unsigned RoundingHacks;
-#if PLATFORM(MAC)
+#if ENABLE(8BIT_TEXTRUN)
TextRun(const LChar* c, unsigned len, float xpos = 0, float expansion = 0, ExpansionBehavior expansionBehavior = AllowTrailingExpansion | ForbidLeadingExpansion, TextDirection direction = LTR, bool directionalOverride = false, bool characterScanForCodePath = true, RoundingHacks roundingHacks = RunRounding | WordRounding)
: m_charactersLength(len)
, m_len(len)
@@ -123,14 +123,10 @@ public:
, m_disableSpacing(false)
, m_tabSize(0)
{
-#if PLATFORM(MAC)
+#if ENABLE(8BIT_TEXTRUN)
if (m_charactersLength && s.is8Bit()) {
- m_data.characters16 = s.characters();
- m_is8Bit = false;
-// FIXME: Change this to:
-// m_data.characters8 = s.characters8();
-// m_is8Bit = true;
-// when other 8 bit rendering changes are landed.
+ m_data.characters8 = s.characters8();
+ m_is8Bit = true;
} else {
m_data.characters16 = s.characters();
m_is8Bit = false;
@@ -147,11 +143,15 @@ public:
TextRun result = *this;
- if (is8Bit())
+#if ENABLE(8BIT_TEXTRUN)
+ if (is8Bit()) {
result.setText(data8(startOffset), length);
- else
- result.setText(data16(startOffset), length);
-
+ return result;
+ }
+#else
+ ASSERT(!is8Bit());
+#endif
+ result.setText(data16(startOffset), length);
return result;
}
@@ -166,7 +166,9 @@ public:
int length() const { return m_len; }
int charactersLength() const { return m_charactersLength; }
+#if ENABLE(8BIT_TEXTRUN)
void setText(const LChar* c, unsigned len) { m_data.characters8 = c; m_len = len; m_is8Bit = true;}
+#endif
void setText(const UChar* c, unsigned len) { m_data.characters16 = c; m_len = len; m_is8Bit = false;}
void setCharactersLength(unsigned charactersLength) { m_charactersLength = charactersLength; }
diff --git a/Source/WebCore/platform/graphics/TiledBacking.h b/Source/WebCore/platform/graphics/TiledBacking.h
index 70012b117..1c74f09a2 100644
--- a/Source/WebCore/platform/graphics/TiledBacking.h
+++ b/Source/WebCore/platform/graphics/TiledBacking.h
@@ -32,21 +32,26 @@ class IntRect;
class TiledBacking {
public:
- TiledBacking()
- : m_scrollingPerformanceLoggingEnabled(0)
- { }
virtual ~TiledBacking() { }
virtual void visibleRectChanged(const IntRect&) = 0;
virtual void setIsInWindow(bool) = 0;
- virtual void setCanHaveScrollbars(bool) = 0;
- virtual void forceRepaint() = 0;
- void setScrollingPerformanceLoggingEnabled(bool flag) { m_scrollingPerformanceLoggingEnabled = flag; }
- bool scrollingPerformanceLoggingEnabled() const { return m_scrollingPerformanceLoggingEnabled; }
+ enum {
+ CoverageForVisibleArea = 0,
+ CoverageForVerticalScrolling = 1 << 0,
+ CoverageForHorizontalScrolling = 1 << 1,
+ CoverageForScrolling = CoverageForVerticalScrolling | CoverageForHorizontalScrolling
+ };
+ typedef unsigned TileCoverage;
+
+ virtual void setTileCoverage(TileCoverage) = 0;
+ virtual TileCoverage tileCoverage() const = 0;
+
+ virtual void forceRepaint() = 0;
-private:
- bool m_scrollingPerformanceLoggingEnabled;
+ virtual void setScrollingPerformanceLoggingEnabled(bool) = 0;
+ virtual bool scrollingPerformanceLoggingEnabled() const = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
index a19f6a616..c564dbed0 100644
--- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp
@@ -116,9 +116,9 @@ void TiledBackingStore::updateTileBuffers()
Vector<RefPtr<Tile> > dirtyTiles;
TileMap::iterator end = m_tiles.end();
for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
- if (!it->second->isDirty())
+ if (!it->value->isDirty())
continue;
- dirtyTiles.append(it->second);
+ dirtyTiles.append(it->value);
}
if (dirtyTiles.isEmpty()) {
@@ -255,10 +255,11 @@ void TiledBackingStore::createTiles()
if (visibleRect.isEmpty())
return;
- IntRect keepRect;
IntRect coverRect;
+ IntRect keepRect;
computeCoverAndKeepRect(visibleRect, coverRect, keepRect);
+ setCoverRect(coverRect);
setKeepRect(keepRect);
// Resize tiles at the edge in case the contents size has changed, but only do so
@@ -401,13 +402,13 @@ bool TiledBackingStore::resizeEdgeTiles()
Vector<Tile::Coordinate> tilesToRemove;
TileMap::iterator end = m_tiles.end();
for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
- Tile::Coordinate tileCoordinate = it->second->coordinate();
- IntRect tileRect = it->second->rect();
+ Tile::Coordinate tileCoordinate = it->value->coordinate();
+ IntRect tileRect = it->value->rect();
IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate);
if (expectedTileRect.isEmpty())
tilesToRemove.append(tileCoordinate);
else if (expectedTileRect != tileRect) {
- it->second->resize(expectedTileRect.size());
+ it->value->resize(expectedTileRect.size());
wasResized = true;
}
}
@@ -426,8 +427,8 @@ void TiledBackingStore::setKeepRect(const IntRect& keepRect)
Vector<Tile::Coordinate> toRemove;
TileMap::iterator end = m_tiles.end();
for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
- Tile::Coordinate coordinate = it->second->coordinate();
- FloatRect tileRect = it->second->rect();
+ Tile::Coordinate coordinate = it->value->coordinate();
+ FloatRect tileRect = it->value->rect();
if (!tileRect.intersects(keepRectF))
toRemove.append(coordinate);
}
diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.h b/Source/WebCore/platform/graphics/TiledBackingStore.h
index 8d662e4c4..b3c365c35 100644
--- a/Source/WebCore/platform/graphics/TiledBackingStore.h
+++ b/Source/WebCore/platform/graphics/TiledBackingStore.h
@@ -72,6 +72,7 @@ public:
Tile::Coordinate tileCoordinateForPoint(const IntPoint&) const;
double tileDistance(const IntRect& viewport, const Tile::Coordinate&) const;
+ IntRect coverRect() const { return m_coverRect; }
bool visibleAreaIsCovered() const;
void removeAllNonVisibleTiles();
@@ -94,6 +95,7 @@ private:
void commitScaleChange();
bool resizeEdgeTiles();
+ void setCoverRect(const IntRect& rect) { m_coverRect = rect; }
void setKeepRect(const IntRect&);
PassRefPtr<Tile> tileAt(const Tile::Coordinate&) const;
@@ -125,6 +127,7 @@ private:
FloatPoint m_trajectoryVector;
IntRect m_visibleRect;
+ IntRect m_coverRect;
IntRect m_keepRect;
IntRect m_rect;
diff --git a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
index d9a9e6e42..b9a91730b 100644
--- a/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
+++ b/Source/WebCore/platform/graphics/WOFFFileFormat.cpp
@@ -30,30 +30,7 @@
#if !USE(OPENTYPE_SANITIZER)
#include "SharedBuffer.h"
-
-#if OS(UNIX)
-#include <netinet/in.h>
-#endif
-
-#if OS(WINDOWS)
-#if CPU(BIG_ENDIAN)
-#define ntohs(x) ((uint16_t)(x))
-#define htons(x) ((uint16_t)(x))
-#define ntohl(x) ((uint32_t)(x))
-#define htonl(x) ((uint32_t)(x))
-#elif CPU(MIDDLE_ENDIAN)
-#define ntohs(x) ((unit16_t)(x))
-#define htons(x) ((uint16_t)(x))
-#define ntohl(x) ((uint32_t)((((uint32_t)(x) & 0xffff0000) >> 16) | (((uint32_t)(x) & 0xffff) << 16))
-#define htonl(x) ntohl(x)
-#else
-#define ntohs(x) ((uint16_t)((((uint16_t)(x) & 0xff00) >> 8) | (((uint16_t)(x) & 0x00ff) << 8)))
-#define htons(x) ntohs(x)
-#define ntohl(x) ((uint32_t)((((uint32_t)(x) & 0xff000000) >> 24) | (((uint32_t)(x) & 0x00ff0000) >> 8) | \
- (((uint32_t)(x) & 0x0000ff00) << 8) | (((uint32_t)(x) & 0x000000ff) << 24)))
-#define htonl(x) ntohl(x)
-#endif
-#endif // OS(WINDOWS)
+#include <wtf/ByteOrder.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp
index f061ec470..15ca61773 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.cpp
+++ b/Source/WebCore/platform/graphics/WidthIterator.cpp
@@ -27,7 +27,6 @@
#include "Latin1TextIterator.h"
#include "SimpleFontData.h"
#include "SurrogatePairAwareTextIterator.h"
-#include "TextRun.h"
#include <wtf/MathExtras.h>
using namespace WTF;
@@ -43,6 +42,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
, m_runWidthSoFar(0)
, m_isAfterExpansion(!run.allowsLeadingExpansion())
, m_finalRoundingWidth(0)
+ , m_typesettingFeatures(font->typesettingFeatures())
, m_fallbackFonts(fallbackFonts)
, m_accountForGlyphBounds(accountForGlyphBounds)
, m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
@@ -84,6 +84,62 @@ GlyphData WidthIterator::glyphDataForCharacter(UChar32 character, bool mirror, i
return m_font->glyphDataForCharacter(character, mirror);
}
+struct OriginalAdvancesForCharacterTreatedAsSpace {
+public:
+ OriginalAdvancesForCharacterTreatedAsSpace(bool isSpace, float advanceBefore, float advanceAt)
+ : characterIsSpace(isSpace)
+ , advanceBeforeCharacter(advanceBefore)
+ , advanceAtCharacter(advanceAt)
+ {
+ }
+
+ bool characterIsSpace;
+ float advanceBeforeCharacter;
+ float advanceAtCharacter;
+};
+
+typedef Vector<pair<int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;
+
+static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
+{
+ ASSERT(typesettingFeatures & (Kerning | Ligatures));
+
+ if (!glyphBuffer)
+ return 0;
+
+ int glyphBufferSize = glyphBuffer->size();
+ if (glyphBuffer->size() <= lastGlyphCount + 1)
+ return 0;
+
+ GlyphBufferAdvance* advances = glyphBuffer->advances(0);
+ float widthDifference = 0;
+ for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+ widthDifference -= advances[i].width();
+
+ if (!ltr)
+ glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
+
+ fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures);
+
+ if (!ltr)
+ glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
+
+ for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) {
+ int spaceOffset = charactersTreatedAsSpace[i].first;
+ const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second;
+ if (spaceOffset && !originalAdvances.characterIsSpace)
+ glyphBuffer->advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter);
+ glyphBuffer->advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter);
+ }
+ charactersTreatedAsSpace.clear();
+
+ for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+ widthDifference += advances[i].width();
+
+ lastGlyphCount = glyphBufferSize;
+ return widthDifference;
+}
+
template <typename TextIterator>
inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
{
@@ -99,10 +155,11 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
const SimpleFontData* primaryFont = m_font->primaryFont();
const SimpleFontData* lastFontData = primaryFont;
+ int lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
UChar32 character = 0;
unsigned clusterLength = 0;
-
+ CharactersTreatedAsSpace charactersTreatedAsSpace;
while (textIterator.consume(character, clusterLength)) {
unsigned advanceLength = clusterLength;
const GlyphData& glyphData = glyphDataForCharacter(character, rtl, textIterator.currentCharacter(), advanceLength);
@@ -132,6 +189,9 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
}
if (fontData != lastFontData && width) {
+ if (shouldApplyFontTransforms())
+ m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
+
lastFontData = fontData;
if (m_fallbackFonts && fontData != primaryFont) {
// FIXME: This does a little extra work that could be avoided if
@@ -187,6 +247,10 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
m_isAfterExpansion = false;
}
+ if (shouldApplyFontTransforms() && glyphBuffer && Font::treatAsSpace(character))
+ charactersTreatedAsSpace.append(make_pair(glyphBuffer->size(),
+ OriginalAdvancesForCharacterTreatedAsSpace(character == ' ', glyphBuffer->size() ? glyphBuffer->advanceAt(glyphBuffer->size() - 1) : 0, width)));
+
if (m_accountForGlyphBounds) {
bounds = fontData->boundsForGlyph(glyph);
if (!textIterator.currentCharacter())
@@ -239,6 +303,9 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
}
}
+ if (shouldApplyFontTransforms())
+ m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
+
unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
m_currentCharacter = textIterator.currentCharacter();
m_runWidthSoFar += widthSinceLastRounding;
@@ -265,15 +332,15 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
return advanceInternal(textIterator, glyphBuffer);
}
-bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
+bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer)
{
- int oldSize = glyphBuffer->size();
- advance(m_currentCharacter + 1, glyphBuffer);
+ int oldSize = glyphBuffer.size();
+ advance(m_currentCharacter + 1, &glyphBuffer);
float w = 0;
- for (int i = oldSize; i < glyphBuffer->size(); ++i)
- w += glyphBuffer->advanceAt(i);
+ for (int i = oldSize; i < glyphBuffer.size(); ++i)
+ w += glyphBuffer.advanceAt(i);
width = w;
- return glyphBuffer->size() > oldSize;
+ return glyphBuffer.size() > oldSize;
}
}
diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h
index ce475dafa..1996a0978 100644
--- a/Source/WebCore/platform/graphics/WidthIterator.h
+++ b/Source/WebCore/platform/graphics/WidthIterator.h
@@ -22,7 +22,9 @@
#ifndef WidthIterator_h
#define WidthIterator_h
+#include "Font.h"
#include "SVGGlyph.h"
+#include "TextRun.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
@@ -40,8 +42,8 @@ struct WidthIterator {
public:
WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
- unsigned advance(int to, GlyphBuffer* = 0);
- bool advanceOneCharacter(float& width, GlyphBuffer* = 0);
+ unsigned advance(int to, GlyphBuffer*);
+ bool advanceOneCharacter(float& width, GlyphBuffer&);
float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
float minGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_minGlyphBoundingBoxY; }
@@ -57,6 +59,18 @@ public:
Vector<SVGGlyph::ArabicForm>& arabicForms() { return m_arabicForms; }
#endif
+ static bool supportsTypesettingFeatures(const Font& font)
+ {
+#if !PLATFORM(MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+ return !font.typesettingFeatures();
+#else
+ if (!font.isPrinterFont())
+ return !font.typesettingFeatures();
+
+ return !(font.typesettingFeatures() & ~(Kerning | Ligatures));
+#endif
+ }
+
const Font* m_font;
const TextRun& m_run;
@@ -78,6 +92,9 @@ private:
template <typename TextIterator>
inline unsigned advanceInternal(TextIterator&, GlyphBuffer*);
+ bool shouldApplyFontTransforms() const { return m_run.length() > 1 && (m_typesettingFeatures & (Kerning | Ligatures)); }
+
+ TypesettingFeatures m_typesettingFeatures;
HashSet<const SimpleFontData*>* m_fallbackFonts;
bool m_accountForGlyphBounds;
float m_maxGlyphBoundingBoxY;
diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
index fc2a2177c..8ee5baf59 100644
--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
@@ -33,9 +33,9 @@
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "GraphicsLayer.h"
#include "KURL.h"
#include "Logging.h"
+#include "PlatformLayer.h"
#include "SoftLinking.h"
#include "TimeRanges.h"
#include <CoreMedia/CoreMedia.h>
diff --git a/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp b/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
index 81d862981..75faa0caa 100644
--- a/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
+++ b/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
@@ -156,7 +156,7 @@ private:
virtual GraphicsLayer::CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return GraphicsLayer::CompositingCoordinatesBottomUp; }
virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& inClip) { }
virtual bool platformCALayerShowDebugBorders() const { return false; }
- virtual bool platformCALayerShowRepaintCounter() const { return false; }
+ virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const { return false; }
virtual int platformCALayerIncrementRepaintCount() { return 0; }
virtual bool platformCALayerContentsOpaque() const { return false; }
@@ -915,7 +915,7 @@ AVFWrapper* AVFWrapper::avfWrapperForCallbackContext(void* context)
if (it == map().end())
return 0;
- return it->second;
+ return it->value;
}
void AVFWrapper::scheduleDisconnectAndDelete()
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
index d44a30c73..e70db1a98 100644
--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
@@ -29,8 +29,9 @@
#if ENABLE(VIDEO) && USE(AVFOUNDATION)
#include "MediaPlayerPrivateAVFoundation.h"
+#include <wtf/HashMap.h>
-OBJC_CLASS AVAsset;
+OBJC_CLASS AVURLAsset;
OBJC_CLASS AVPlayer;
OBJC_CLASS AVPlayerItem;
OBJC_CLASS AVPlayerItemVideoOutput;
@@ -38,6 +39,11 @@ OBJC_CLASS AVPlayerLayer;
OBJC_CLASS AVAssetImageGenerator;
OBJC_CLASS WebCoreAVFMovieObserver;
+#if ENABLE(ENCRYPTED_MEDIA) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+OBJC_CLASS WebCoreAVFLoaderDelegate;
+OBJC_CLASS AVAssetResourceLoadingRequest;
+#endif
+
#ifndef __OBJC__
typedef struct objc_object *id;
#endif
@@ -56,6 +62,10 @@ public:
void setAsset(id);
virtual void tracksChanged();
+#if ENABLE(ENCRYPTED_MEDIA) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ bool shouldWaitForLoadingOfResource(AVAssetResourceLoadingRequest*);
+#endif
+
private:
MediaPlayerPrivateAVFoundationObjC(MediaPlayer*);
@@ -63,6 +73,10 @@ private:
static PassOwnPtr<MediaPlayerPrivateInterface> create(MediaPlayer*);
static void getSupportedTypes(HashSet<String>& types);
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs, const KURL&);
+#if ENABLE(ENCRYPTED_MEDIA)
+ static MediaPlayer::SupportsType extendedSupportsType(const String& type, const String& codecs, const String& keySystem, const KURL&);
+#endif
+
static bool isAvailable();
virtual void cancelLoad();
@@ -124,7 +138,13 @@ private:
void paintWithVideoOutput(GraphicsContext*, const IntRect&);
#endif
- RetainPtr<AVAsset> m_avAsset;
+#if ENABLE(ENCRYPTED_MEDIA)
+ virtual MediaPlayer::MediaKeyException addKey(const String&, const unsigned char*, unsigned, const unsigned char*, unsigned, const String&);
+ virtual MediaPlayer::MediaKeyException generateKeyRequest(const String&, const unsigned char*, unsigned);
+ virtual MediaPlayer::MediaKeyException cancelKeyRequest(const String&, const String&);
+#endif
+
+ RetainPtr<AVURLAsset> m_avAsset;
RetainPtr<AVPlayer> m_avPlayer;
RetainPtr<AVPlayerItem> m_avPlayerItem;
RetainPtr<AVPlayerLayer> m_videoLayer;
@@ -139,6 +159,12 @@ private:
RetainPtr<AVPlayerItemVideoOutput> m_videoOutput;
RetainPtr<CVPixelBufferRef> m_lastImage;
#endif
+
+#if ENABLE(ENCRYPTED_MEDIA) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ RetainPtr<WebCoreAVFLoaderDelegate> m_loaderDelegate;
+ HashMap<String, RetainPtr<AVAssetResourceLoadingRequest> > m_keyURIToRequestMap;
+ HashMap<String, RetainPtr<AVAssetResourceLoadingRequest> > m_sessionIDToRequestMap;
+#endif
};
}
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
index cf75d0cf6..5d9ddd9cb 100644
--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
@@ -30,6 +30,7 @@
#import "MediaPlayerPrivateAVFoundationObjC.h"
#import "BlockExceptions.h"
+#import "DataView.h"
#import "FloatConversion.h"
#import "FrameView.h"
#import "FloatConversion.h"
@@ -39,9 +40,13 @@
#import "SecurityOrigin.h"
#import "SoftLinking.h"
#import "TimeRanges.h"
+#import "UUID.h"
#import "WebCoreSystemInterface.h"
#import <objc/objc-runtime.h>
#import <wtf/UnusedParam.h>
+#import <wtf/Uint8Array.h>
+#import <wtf/Uint16Array.h>
+#import <wtf/Uint32Array.h>
#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>
@@ -112,6 +117,25 @@ enum MediaPlayerAVFoundationObservationContext {
-(void)observeValueForKeyPath:keyPath ofObject:(id)object change:(NSDictionary *)change context:(MediaPlayerAVFoundationObservationContext)context;
@end
+#if ENABLE(ENCRYPTED_MEDIA)
+@interface WebCoreAVFLoaderDelegate : NSObject<AVAssetResourceLoaderDelegate> {
+ MediaPlayerPrivateAVFoundationObjC* m_callback;
+}
+- (id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC*)callback;
+- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest;
+@end
+
+static dispatch_queue_t globalLoaderDelegateQueue()
+{
+ static dispatch_queue_t globalQueue;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ globalQueue = dispatch_queue_create("WebCoreAVFLoaderDelegate queue", DISPATCH_QUEUE_SERIAL);
+ });
+ return globalQueue;
+}
+#endif
+
namespace WebCore {
static NSArray *assetMetadataKeyNames();
@@ -132,7 +156,11 @@ PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivateAVFoundationObjC::crea
void MediaPlayerPrivateAVFoundationObjC::registerMediaEngine(MediaEngineRegistrar registrar)
{
if (isAvailable())
+#if ENABLE(ENCRYPTED_MEDIA)
+ registrar(create, getSupportedTypes, extendedSupportsType, 0, 0, 0);
+#else
registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
+#endif
}
MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC(MediaPlayer* player)
@@ -140,6 +168,9 @@ MediaPlayerPrivateAVFoundationObjC::MediaPlayerPrivateAVFoundationObjC(MediaPlay
, m_objcObserver(AdoptNS, [[WebCoreAVFMovieObserver alloc] initWithCallback:this])
, m_videoFrameHasDrawn(false)
, m_haveCheckedPlayability(false)
+#if ENABLE(ENCRYPTED_MEDIA)
+ , m_loaderDelegate(AdoptNS, [[WebCoreAVFLoaderDelegate alloc] initWithCallback:this])
+#endif
{
}
@@ -304,6 +335,10 @@ void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const String& url)
NSURL *cocoaURL = KURL(ParsedURLString, url);
m_avAsset.adoptNS([[AVURLAsset alloc] initWithURL:cocoaURL options:options.get()]);
+#if ENABLE(ENCRYPTED_MEDIA)
+ [[m_avAsset.get() resourceLoader] setDelegate:m_loaderDelegate.get() queue:globalLoaderDelegateQueue()];
+#endif
+
m_haveCheckedPlayability = false;
setDelayCallbacks(false);
@@ -725,6 +760,59 @@ MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationObjC::supportsType(const
return [AVURLAsset isPlayableExtendedMIMEType:typeString] ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;;
}
+#if ENABLE(ENCRYPTED_MEDIA)
+static bool keySystemIsSupported(const String& keySystem)
+{
+ if (equalIgnoringCase(keySystem, "com.apple.lskd") || equalIgnoringCase(keySystem, "com.apple.lskd.1_0"))
+ return true;
+
+ return false;
+}
+
+MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationObjC::extendedSupportsType(const String& type, const String& codecs, const String& keySystem, const KURL& url)
+{
+ // From: <http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-canplaytype>
+ // In addition to the steps in the current specification, this method must run the following steps:
+
+ // 1. Check whether the Key System is supported with the specified container and codec type(s) by following the steps for the first matching condition from the following list:
+ // If keySystem is null, continue to the next step.
+ if (keySystem.isNull() || keySystem.isEmpty())
+ return supportsType(type, codecs, url);
+
+ // If keySystem contains an unrecognized or unsupported Key System, return the empty string
+ if (!keySystemIsSupported(keySystem))
+ return MediaPlayer::IsNotSupported;
+
+ // If the Key System specified by keySystem does not support decrypting the container and/or codec specified in the rest of the type string.
+ // (AVFoundation does not provide an API which would allow us to determine this, so this is a no-op)
+
+ // 2. Return "maybe" or "probably" as appropriate per the existing specification of canPlayType().
+ return supportsType(type, codecs, url);
+}
+
+bool MediaPlayerPrivateAVFoundationObjC::shouldWaitForLoadingOfResource(AVAssetResourceLoadingRequest* avRequest)
+{
+ String keyURI = [[[avRequest request] URL] absoluteString];
+
+ // Create an initData with the following layout:
+ // [4 bytes: keyURI size], [keyURI size bytes: keyURI]
+ unsigned keyURISize = keyURI.length() * sizeof(UChar);
+ RefPtr<ArrayBuffer> initDataBuffer = ArrayBuffer::create(4 + keyURISize, 1);
+ RefPtr<DataView> initDataView = DataView::create(initDataBuffer, 0, initDataBuffer->byteLength());
+ ExceptionCode ec = 0;
+ initDataView->setUint32(0, keyURISize, true, ec);
+
+ RefPtr<Uint16Array> keyURIArray = Uint16Array::create(initDataBuffer, 4, keyURI.length());
+ keyURIArray->setRange(keyURI.characters(), keyURI.length() / sizeof(unsigned char), 0);
+
+ if (!player()->keyNeeded("com.apple.lskd", emptyString(), static_cast<const unsigned char*>(initDataBuffer->data()), initDataBuffer->byteLength()))
+ return false;
+
+ m_keyURIToRequestMap.set(keyURI, avRequest);
+ return true;
+}
+#endif
+
bool MediaPlayerPrivateAVFoundationObjC::isAvailable()
{
return AVFoundationLibrary() && CoreMediaLibrary();
@@ -897,6 +985,133 @@ void MediaPlayerPrivateAVFoundationObjC::paintWithVideoOutput(GraphicsContext* c
#endif
+#if ENABLE(ENCRYPTED_MEDIA)
+
+static bool extractKeyURIKeyIDAndCertificateFromInitData(Uint8Array* initData, String& keyURI, String& keyID, RefPtr<Uint8Array>& certificate)
+{
+ // initData should have the following layout:
+ // [4 bytes: keyURI length][N bytes: keyURI][4 bytes: contentID length], [N bytes: contentID], [4 bytes: certificate length][N bytes: certificate]
+ if (initData->byteLength() < 4)
+ return false;
+
+ RefPtr<ArrayBuffer> initDataBuffer = initData->buffer();
+
+ // Use a DataView to read uint32 values from the buffer, as Uint32Array requires the reads be aligned on 4-byte boundaries.
+ RefPtr<DataView> initDataView = DataView::create(initDataBuffer, 0, initDataBuffer->byteLength());
+ uint32_t offset = 0;
+ ExceptionCode ec = 0;
+
+ uint32_t keyURILength = initDataView->getUint32(offset, true, ec);
+ offset += 4;
+ if (ec || offset + keyURILength > initData->length())
+ return false;
+
+ RefPtr<Uint16Array> keyURIArray = Uint16Array::create(initDataBuffer, offset, keyURILength);
+ if (!keyURIArray)
+ return false;
+
+ keyURI = String(keyURIArray->data(), keyURILength / sizeof(unsigned short));
+ offset += keyURILength;
+
+ uint32_t keyIDLength = initDataView->getUint32(offset, true, ec);
+ offset += 4;
+ if (ec || offset + keyIDLength > initData->length())
+ return false;
+
+ RefPtr<Uint16Array> keyIDArray = Uint16Array::create(initDataBuffer, offset, keyIDLength);
+ if (!keyIDArray)
+ return false;
+
+ keyID = String(keyIDArray->data(), keyIDLength / sizeof(unsigned short));
+ offset += keyIDLength;
+
+ uint32_t certificateLength = initDataView->getUint32(offset, true, ec);
+ offset += 4;
+ if (ec || offset + certificateLength > initData->length())
+ return false;
+
+ certificate = Uint8Array::create(initDataBuffer, offset, certificateLength);
+ if (!certificate)
+ return false;
+
+ return true;
+}
+
+MediaPlayer::MediaKeyException MediaPlayerPrivateAVFoundationObjC::generateKeyRequest(const String& keySystem, const unsigned char* initDataPtr, unsigned initDataLength)
+{
+ if (!keySystemIsSupported(keySystem))
+ return MediaPlayer::KeySystemNotSupported;
+
+ RefPtr<Uint8Array> initData = Uint8Array::create(initDataPtr, initDataLength);
+ String keyURI;
+ String keyID;
+ RefPtr<Uint8Array> certificate;
+ if (!extractKeyURIKeyIDAndCertificateFromInitData(initData.get(), keyURI, keyID, certificate))
+ return MediaPlayer::InvalidPlayerState;
+
+ if (!m_keyURIToRequestMap.contains(keyURI))
+ return MediaPlayer::InvalidPlayerState;
+
+ String sessionID = createCanonicalUUIDString();
+
+ RetainPtr<AVAssetResourceLoadingRequest> avRequest = m_keyURIToRequestMap.get(keyURI);
+
+ RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:certificate->baseAddress() length:certificate->byteLength()]);
+ NSString* assetStr = keyID;
+ RetainPtr<NSData> assetID = [NSData dataWithBytes: [assetStr cStringUsingEncoding:NSUTF8StringEncoding] length:[assetStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
+ NSError* error = 0;
+ RetainPtr<NSData> keyRequest = [avRequest.get() streamingContentKeyRequestDataForApp:certificateData.get() contentIdentifier:assetID.get() options:nil error:&error];
+
+ if (!keyRequest) {
+ NSError* underlyingError = [[error userInfo] objectForKey:NSUnderlyingErrorKey];
+ player()->keyError(keySystem, sessionID, MediaPlayerClient::DomainError, [underlyingError code]);
+ return MediaPlayer::NoError;
+ }
+
+ RefPtr<ArrayBuffer> keyRequestBuffer = ArrayBuffer::create([keyRequest.get() bytes], [keyRequest.get() length]);
+ RefPtr<Uint8Array> keyRequestArray = Uint8Array::create(keyRequestBuffer, 0, keyRequestBuffer->byteLength());
+ player()->keyMessage(keySystem, sessionID, keyRequestArray->data(), keyRequestArray->byteLength());
+
+ // Move ownership of the AVAssetResourceLoadingRequestfrom the keyIDToRequestMap to the sessionIDToRequestMap:
+ m_sessionIDToRequestMap.set(sessionID, avRequest);
+ m_keyURIToRequestMap.remove(keyURI);
+
+ return MediaPlayer::NoError;
+}
+
+MediaPlayer::MediaKeyException MediaPlayerPrivateAVFoundationObjC::addKey(const String& keySystem, const unsigned char* keyPtr, unsigned keyLength, const unsigned char* initDataPtr, unsigned initDataLength, const String& sessionID)
+{
+ if (!keySystemIsSupported(keySystem))
+ return MediaPlayer::KeySystemNotSupported;
+
+ if (!m_sessionIDToRequestMap.contains(sessionID))
+ return MediaPlayer::InvalidPlayerState;
+
+ RetainPtr<AVAssetResourceLoadingRequest> avRequest = m_sessionIDToRequestMap.get(sessionID);
+ RetainPtr<NSData> keyData = adoptNS([[NSData alloc] initWithBytes:keyPtr length:keyLength]);
+ [avRequest.get() finishLoadingWithResponse:nil data:keyData.get() redirect:nil];
+ m_sessionIDToRequestMap.remove(sessionID);
+
+ player()->keyAdded(keySystem, sessionID);
+
+ UNUSED_PARAM(initDataPtr);
+ UNUSED_PARAM(initDataLength);
+ return MediaPlayer::NoError;
+}
+
+MediaPlayer::MediaKeyException MediaPlayerPrivateAVFoundationObjC::cancelKeyRequest(const String& keySystem, const String& sessionID)
+{
+ if (!keySystemIsSupported(keySystem))
+ return MediaPlayer::KeySystemNotSupported;
+
+ if (!m_sessionIDToRequestMap.contains(sessionID))
+ return MediaPlayer::InvalidPlayerState;
+
+ m_sessionIDToRequestMap.remove(sessionID);
+ return MediaPlayer::NoError;
+}
+#endif
+
NSArray* assetMetadataKeyNames()
{
static NSArray* keys;
@@ -1024,4 +1239,26 @@ NSArray* itemKVOProperties()
@end
+#if ENABLE(ENCRYPTED_MEDIA)
+@implementation WebCoreAVFLoaderDelegate
+
+- (id)initWithCallback:(MediaPlayerPrivateAVFoundationObjC*)callback
+{
+ m_callback = callback;
+ return [super init];
+}
+
+- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
+{
+ UNUSED_PARAM(resourceLoader);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (!m_callback->shouldWaitForLoadingOfResource(loadingRequest))
+ [loadingRequest finishLoadingWithError:nil];
+ });
+ return TRUE;
+}
+
+@end
+#endif
+
#endif
diff --git a/Source/WebCore/platform/graphics/blackberry/DisplayRefreshMonitorBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/DisplayRefreshMonitorBlackBerry.cpp
index b85afc345..0281aa1e5 100644
--- a/Source/WebCore/platform/graphics/blackberry/DisplayRefreshMonitorBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/DisplayRefreshMonitorBlackBerry.cpp
@@ -84,7 +84,7 @@ void DisplayRefreshMonitor::displayLinkFired()
m_previousFrameDone = false;
- m_timestamp = currentTime();
+ m_monotonicAnimationStartTime = monotonicallyIncreasingTime();
callOnMainThread(handleDisplayRefreshedNotificationOnMainThread, this);
m_mutex.unlock();
diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp
index d3002cfd1..95e023d14 100644
--- a/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/GraphicsContext3DBlackBerry.cpp
@@ -130,6 +130,7 @@ GraphicsContext3D::~GraphicsContext3D()
::glDeleteFramebuffers(1, &m_fbo);
}
+ m_compositingLayer = 0; // Must release compositing layer before destroying the context.
BlackBerry::Platform::Graphics::destroyWebGLContext(m_context);
}
@@ -233,46 +234,46 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
void GraphicsContext3D::logFrameBufferStatus(int line)
{
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "Checking FrameBuffer status at line %d: ", line);
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "Checking FrameBuffer status at line %d: ", line);
switch (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) {
case GL_FRAMEBUFFER_COMPLETE:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "COMPLETE | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "COMPLETE | ");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE ATTACHMENT | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE ATTACHMENT | ");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "MISSING ATTACHMENT | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "MISSING ATTACHMENT | ");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE DIMENSIONS | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE DIMENSIONS | ");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "UNSUPPORTED | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "UNSUPPORTED | ");
break;
case FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE MULTISAMPLE | ");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INCOMPLETE MULTISAMPLE | ");
break;
}
switch (glGetError()) {
case GL_NO_ERROR:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "NO ERROR");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "NO ERROR");
break;
case GL_INVALID_ENUM:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID ENUM");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INVALID ENUM");
break;
case GL_INVALID_VALUE:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID VALUE");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INVALID VALUE");
break;
case GL_INVALID_OPERATION:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "INVALID OPERATION");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "INVALID OPERATION");
break;
case GL_OUT_OF_MEMORY:
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "OUT OF MEMORY");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "OUT OF MEMORY");
break;
}
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "\n");
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "\n");
}
void GraphicsContext3D::readPixelsIMG(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
index 195070d3a..c1a703acd 100644
--- a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.cpp
@@ -48,6 +48,7 @@
#include "FloatConversion.h"
#include "FloatRect.h"
+#include "GraphicsLayerFactory.h"
#include "Image.h"
#include "LayerAnimation.h"
#include "LayerWebKitThread.h"
@@ -79,6 +80,14 @@ static void clearLayerBackgroundColor(LayerWebKitThread& layer)
layer.setBackgroundColor(Color::transparent);
}
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
+{
+ if (!factory)
+ return adoptPtr(new GraphicsLayerBlackBerry(client));
+
+ return factory->createGraphicsLayer(client);
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return adoptPtr(new GraphicsLayerBlackBerry(client));
diff --git a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.h
index d8d6b6ae9..5c861264e 100644
--- a/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.h
+++ b/Source/WebCore/platform/graphics/blackberry/GraphicsLayerBlackBerry.h
@@ -116,10 +116,10 @@ public:
virtual void setDebugBackgroundColor(const Color&);
virtual void setDebugBorder(const Color&, float borderWidth);
- void notifySyncRequired()
+ void notifyFlushRequired()
{
if (m_client)
- m_client->notifySyncRequired(this);
+ m_client->notifyFlushRequired(this);
}
void notifyAnimationStarted(double time)
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp
index 706d6ab67..454af1a0c 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp
@@ -197,8 +197,8 @@ FloatQuad LayerCompositingThread::getTransformedHolePunchRect() const
drawRect.move(-location.x(), -location.y());
#if DEBUG_VIDEO_CLIPPING
- IntRect drawRectInWebKitDocumentCoordination = m_layerRenderer->toWebKitDocumentCoordinates(m_drawRect);
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "LayerCompositingThread::getTransformedHolePunchRect() - drawRect=(x=%d,y=%d,width=%d,height=%d) clipRect=(x=%d,y=%d,width=%d,height=%d) clippedRect=(x=%d,y=%d,width=%d,height=%d).",
+ IntRect drawRectInWebKitDocumentCoordination = m_layerRenderer->toWebKitDocumentCoordinates(m_drawRect);
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "LayerCompositingThread::getTransformedHolePunchRect() - drawRect=(x=%d,y=%d,width=%d,height=%d) clipRect=(x=%d,y=%d,width=%d,height=%d) clippedRect=(x=%d,y=%d,width=%d,height=%d).",
drawRectInWebKitDocumentCoordination.x(), drawRectInWebKitDocumentCoordination.y(), drawRectInWebKitDocumentCoordination.width(), drawRectInWebKitDocumentCoordination.height(),
m_holePunchClipRect.x(), m_holePunchClipRect.y(), m_holePunchClipRect.width(), m_holePunchClipRect.height(),
drawRect.x(), drawRect.y(), drawRect.width(), drawRect.height());
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp b/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp
index 83eacacc0..cd2801e2d 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/LayerTiler.cpp
@@ -370,8 +370,8 @@ void LayerTiler::layerVisibilityChanged(LayerCompositingThread*, bool visible)
}
for (TileMap::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) {
- TileIndex index = (*it).first;
- LayerTile* tile = (*it).second;
+ TileIndex index = (*it).key;
+ LayerTile* tile = (*it).value;
tile->setVisible(false);
}
}
@@ -385,21 +385,21 @@ void LayerTiler::uploadTexturesIfNeeded(LayerCompositingThread*)
TileJobsMap::const_iterator tileJobsIterEnd = tileJobsMap.end();
for (TileJobsMap::const_iterator tileJobsIter = tileJobsMap.begin(); tileJobsIter != tileJobsIterEnd; ++tileJobsIter) {
- IntPoint origin = originOfTile(tileJobsIter->first);
+ IntPoint origin = originOfTile(tileJobsIter->key);
- LayerTile* tile = m_tiles.get(tileJobsIter->first);
+ LayerTile* tile = m_tiles.get(tileJobsIter->key);
if (!tile) {
if (origin.x() >= m_requiredTextureSize.width() || origin.y() >= m_requiredTextureSize.height())
continue;
tile = new LayerTile();
- m_tiles.add(tileJobsIter->first, tile);
+ m_tiles.add(tileJobsIter->key, tile);
}
IntRect tileRect(origin, tileSize());
tileRect.setWidth(min(m_requiredTextureSize.width() - tileRect.x(), tileRect.width()));
tileRect.setHeight(min(m_requiredTextureSize.height() - tileRect.y(), tileRect.height()));
- performTileJob(tile, *tileJobsIter->second, tileRect);
+ performTileJob(tile, *tileJobsIter->value, tileRect);
}
m_textureJobs.clear();
@@ -442,11 +442,11 @@ void LayerTiler::addTileJob(const TileIndex& index, const TextureJob& job, TileJ
return;
// In this case we leave the previous job.
- if (job.m_type == TextureJob::DirtyContents && result.iterator->second->m_type == TextureJob::DiscardContents)
+ if (job.m_type == TextureJob::DirtyContents && result.iterator->value->m_type == TextureJob::DiscardContents)
return;
// Override the previous job.
- result.iterator->second = &job;
+ result.iterator->value = &job;
}
void LayerTiler::performTileJob(LayerTile* tile, const TextureJob& job, const IntRect& tileRect)
@@ -631,7 +631,7 @@ void LayerTiler::deleteTextures(LayerCompositingThread*)
// touching some WebKit thread state.
if (m_tiles.size()) {
for (TileMap::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
- (*it).second->discardContents();
+ (*it).value->discardContents();
m_tiles.clear();
m_contentsDirty = true;
@@ -648,7 +648,7 @@ void LayerTiler::pruneTextures()
// Prune tiles that are no longer needed.
Vector<TileIndex> tilesToDelete;
for (TileMap::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) {
- TileIndex index = (*it).first;
+ TileIndex index = (*it).key;
IntPoint origin = originOfTile(index);
if (origin.x() >= m_requiredTextureSize.width() || origin.y() >= m_requiredTextureSize.height())
@@ -730,7 +730,7 @@ void LayerTiler::bindContentsTexture(LayerCompositingThread*)
if (m_tiles.size() != 1)
return;
- const LayerTile* tile = m_tiles.begin()->second;
+ const LayerTile* tile = m_tiles.begin()->value;
ASSERT(tile->hasTexture());
if (!tile->hasTexture())
diff --git a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
index 42b8bed58..142991cf5 100644
--- a/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/LayerWebKitThread.cpp
@@ -195,11 +195,11 @@ void LayerWebKitThread::setDrawable(bool isDrawable)
void LayerWebKitThread::setNeedsCommit()
{
- // Call notifySyncRequired(), which in this implementation plumbs through to
+ // Call notifyFlushRequired(), which in this implementation plumbs through to
// call scheduleRootLayerCommit() on the WebView, which will cause us to commit
// changes done on the WebKit thread for display on the Compositing thread.
if (m_owner)
- m_owner->notifySyncRequired();
+ m_owner->notifyFlushRequired();
}
void LayerWebKitThread::notifyAnimationStarted(double time)
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
index 867d8158c..ea3c89550 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.cpp
@@ -21,6 +21,7 @@
#if ENABLE(VIDEO)
#include "MediaPlayerPrivateBlackBerry.h"
+#include "AuthenticationChallengeManager.h"
#include "CookieManager.h"
#include "Credential.h"
#include "CredentialStorage.h"
@@ -41,7 +42,6 @@
#include <BlackBerryPlatformSettings.h>
#include <FrameLoaderClientBlackBerry.h>
#include <set>
-#include <string>
#include <wtf/text/CString.h>
#if USE(ACCELERATED_COMPOSITING)
@@ -66,15 +66,15 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
registrar(create, getSupportedTypes, supportsType, 0, 0, 0);
}
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivate::getSupportedTypes(HashSet<WTF::String>& types)
{
- set<string> supported = PlatformPlayer::allSupportedMimeTypes();
- set<string>::iterator i = supported.begin();
+ set<BlackBerry::Platform::String> supported = PlatformPlayer::allSupportedMimeTypes();
+ set<BlackBerry::Platform::String>::iterator i = supported.begin();
for (; i != supported.end(); i++)
- types.add(i->c_str());
+ types.add(*i);
}
-MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs, const KURL&)
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const WTF::String& type, const WTF::String& codecs, const KURL&)
{
if (type.isNull() || type.isEmpty()) {
LOG(Media, "MediaPlayer does not support type; type is null or empty.");
@@ -95,9 +95,9 @@ void MediaPlayerPrivate::notifyAppActivatedEvent(bool activated)
PlatformPlayer::notifyAppActivatedEvent(activated);
}
-void MediaPlayerPrivate::setCertificatePath(const String& caPath)
+void MediaPlayerPrivate::setCertificatePath(const WTF::String& caPath)
{
- PlatformPlayer::setCertificatePath(string(caPath.utf8().data()));
+ PlatformPlayer::setCertificatePath(caPath);
}
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
@@ -114,6 +114,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_userDrivenSeekTimer(this, &MediaPlayerPrivate::userDrivenSeekTimerFired)
, m_lastSeekTime(0)
, m_lastSeekTimePending(false)
+ , m_isAuthenticationChallenging(false)
, m_waitMetadataTimer(this, &MediaPlayerPrivate::waitMetadataTimerFired)
, m_waitMetadataPopDialogCounter(0)
{
@@ -121,6 +122,9 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
MediaPlayerPrivate::~MediaPlayerPrivate()
{
+ if (m_isAuthenticationChallenging)
+ AuthenticationChallengeManager::instance()->cancelAuthenticationChallenge(this);
+
if (isFullscreen()) {
m_webCorePlayer->mediaPlayerClient()->mediaPlayerExitFullscreen();
}
@@ -133,14 +137,14 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
deleteGuardedObject(m_platformPlayer);
}
-void MediaPlayerPrivate::load(const String& url)
+void MediaPlayerPrivate::load(const WTF::String& url)
{
- String modifiedUrl(url);
+ WTF::String modifiedUrl(url);
if (modifiedUrl.startsWith("local://")) {
KURL kurl = KURL(KURL(), modifiedUrl);
kurl.setProtocol("file");
- String tempPath(BlackBerry::Platform::Settings::instance()->applicationLocalDirectory().c_str());
+ WTF::String tempPath(BlackBerry::Platform::Settings::instance()->applicationLocalDirectory().c_str());
tempPath.append(kurl.path());
kurl.setPath(tempPath);
modifiedUrl = kurl.string();
@@ -160,7 +164,7 @@ void MediaPlayerPrivate::load(const String& url)
m_platformPlayer = PlatformPlayer::create(this, tabId, false, modifiedUrl.utf8().data());
#endif
- String cookiePairs;
+ WTF::String cookiePairs;
if (!url.isEmpty())
cookiePairs = cookieManager().getCookie(KURL(ParsedURLString, url.utf8().data()), WithHttpOnlyCookies);
if (!cookiePairs.isEmpty() && cookiePairs.utf8().data())
@@ -691,7 +695,7 @@ void MediaPlayerPrivate::onBuffering(bool flag)
static ProtectionSpace generateProtectionSpaceFromMMRAuthChallenge(const MMRAuthChallenge& authChallenge)
{
- KURL url(ParsedURLString, String(authChallenge.url().c_str()));
+ KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
ASSERT(url.isValid());
return ProtectionSpace(url.host(), url.port(),
@@ -702,7 +706,7 @@ static ProtectionSpace generateProtectionSpaceFromMMRAuthChallenge(const MMRAuth
void MediaPlayerPrivate::onAuthenticationNeeded(MMRAuthChallenge& authChallenge)
{
- KURL url(ParsedURLString, String(authChallenge.url().c_str()));
+ KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
if (!url.isValid())
return;
@@ -713,12 +717,18 @@ void MediaPlayerPrivate::onAuthenticationNeeded(MMRAuthChallenge& authChallenge)
return;
}
- if (frameView() && frameView()->hostWindow())
- frameView()->hostWindow()->platformPageClient()->authenticationChallenge(url, protectionSpace, credential, this);
+ if (!frameView() || !frameView()->hostWindow())
+ return;
+
+ m_isAuthenticationChallenging = true;
+ AuthenticationChallengeManager::instance()->authenticationChallenge(url, protectionSpace, credential,
+ this, frameView()->hostWindow()->platformPageClient());
}
void MediaPlayerPrivate::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential)
{
+ m_isAuthenticationChallenging = false;
+
if (result != AuthenticationChallengeSuccess || !url.isValid())
return;
@@ -729,7 +739,7 @@ void MediaPlayerPrivate::notifyChallengeResult(const KURL& url, const Protection
void MediaPlayerPrivate::onAuthenticationAccepted(const MMRAuthChallenge& authChallenge) const
{
- KURL url(ParsedURLString, String(authChallenge.url().c_str()));
+ KURL url(ParsedURLString, WTF::String(authChallenge.url().c_str()));
if (!url.isValid())
return;
@@ -794,9 +804,9 @@ static WebMediaStreamDescriptor toWebMediaStreamDescriptor(MediaStreamDescriptor
return WebMediaStreamDescriptor(d->label().utf8().data(), audioSources, videoSources);
}
-WebMediaStreamDescriptor MediaPlayerPrivate::lookupMediaStream(const string& url)
+WebMediaStreamDescriptor MediaPlayerPrivate::lookupMediaStream(const BlackBerry::Platform::String& url)
{
- MediaStreamDescriptor* descriptor = MediaStreamRegistry::registry().lookupMediaStreamDescriptor(String::fromUTF8(url.c_str()));
+ MediaStreamDescriptor* descriptor = MediaStreamRegistry::registry().lookupMediaStreamDescriptor(WTF::String::fromUTF8(url.c_str()));
if (!descriptor)
return WebMediaStreamDescriptor();
diff --git a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
index 2629e04f6..7b6654dce 100644
--- a/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
+++ b/Source/WebCore/platform/graphics/blackberry/MediaPlayerPrivateBlackBerry.h
@@ -39,12 +39,12 @@ public:
static PassOwnPtr<MediaPlayerPrivateInterface> create(MediaPlayer*);
static void registerMediaEngine(MediaEngineRegistrar);
- static void getSupportedTypes(HashSet<String>&);
- static MediaPlayer::SupportsType supportsType(const String&, const String&, const KURL&);
+ static void getSupportedTypes(HashSet<WTF::String>&);
+ static MediaPlayer::SupportsType supportsType(const WTF::String&, const WTF::String&, const KURL&);
static void notifyAppActivatedEvent(bool);
- static void setCertificatePath(const String&);
+ static void setCertificatePath(const WTF::String&);
- virtual void load(const String& url);
+ virtual void load(const WTF::String& url);
virtual void cancelLoad();
virtual void prepareToPlay();
@@ -143,15 +143,15 @@ public:
virtual bool isTabVisible() const;
virtual int showErrorDialog(BlackBerry::Platform::PlatformPlayer::Error);
virtual BlackBerry::Platform::Graphics::Window* platformWindow();
- virtual BlackBerry::Platform::WebMediaStreamDescriptor lookupMediaStream(const std::string& url);
+ virtual BlackBerry::Platform::WebMediaStreamDescriptor lookupMediaStream(const BlackBerry::Platform::String& url);
private:
MediaPlayerPrivate(MediaPlayer*);
void updateStates();
- String userAgent(const String&) const;
+ WTF::String userAgent(const WTF::String&) const;
- virtual String engineDescription() const { return "BlackBerry"; }
+ virtual WTF::String engineDescription() const { return "BlackBerry"; }
MediaPlayer* m_webCorePlayer;
BlackBerry::Platform::PlatformPlayer* m_platformPlayer;
@@ -174,6 +174,7 @@ private:
Timer<MediaPlayerPrivate> m_userDrivenSeekTimer;
float m_lastSeekTime;
bool m_lastSeekTimePending;
+ bool m_isAuthenticationChallenging;
void waitMetadataTimerFired(Timer<MediaPlayerPrivate>*);
Timer<MediaPlayerPrivate> m_waitMetadataTimer;
int m_waitMetadataPopDialogCounter;
diff --git a/Source/WebCore/platform/graphics/blackberry/TextureCacheCompositingThread.cpp b/Source/WebCore/platform/graphics/blackberry/TextureCacheCompositingThread.cpp
index 5b6bb8736..d65c4dadd 100644
--- a/Source/WebCore/platform/graphics/blackberry/TextureCacheCompositingThread.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/TextureCacheCompositingThread.cpp
@@ -202,10 +202,10 @@ void TextureCacheCompositingThread::setMemoryUsage(size_t memoryUsage)
PassRefPtr<Texture> TextureCacheCompositingThread::textureForTiledContents(const SkBitmap& contents, const IntRect& tileRect, const TileIndex& index, bool isOpaque)
{
HashMap<ContentsKey, TextureMap>::iterator it = m_cache.add(key(contents), TextureMap()).iterator;
- TextureMap& map = (*it).second;
+ TextureMap& map = (*it).value;
TextureMap::iterator jt = map.add(index, RefPtr<Texture>()).iterator;
- RefPtr<Texture> texture = (*jt).second;
+ RefPtr<Texture> texture = (*jt).value;
if (!texture) {
texture = createTexture();
#if DEBUG_TEXTURE_MEMORY_USAGE
@@ -244,7 +244,7 @@ PassRefPtr<Texture> TextureCacheCompositingThread::textureForColor(const Color&
#endif
m_colors.set(color, texture);
} else
- texture = (*it).second;
+ texture = (*it).value;
// Color textures can't be evicted, so no need for TextureProtector.
diff --git a/Source/WebCore/platform/graphics/blackberry/VideoLayerWebKitThread.cpp b/Source/WebCore/platform/graphics/blackberry/VideoLayerWebKitThread.cpp
index 7492871d2..1fec120d2 100644
--- a/Source/WebCore/platform/graphics/blackberry/VideoLayerWebKitThread.cpp
+++ b/Source/WebCore/platform/graphics/blackberry/VideoLayerWebKitThread.cpp
@@ -65,7 +65,7 @@ void VideoLayerWebKitThread::setHolePunchRect(const IntRect& rect)
{
m_holePunchRect = rect;
#if DEBUG_VIDEO_CLIPPING
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "VideoLayerWebKitThread m_holePunchRect=(x=%d,y=%d,width=%d,height=%d).", m_holePunchRect.x(), m_holePunchRect.y(), m_holePunchRect.width(), m_holePunchRect.height());
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "VideoLayerWebKitThread m_holePunchRect=(x=%d,y=%d,width=%d,height=%d).", m_holePunchRect.x(), m_holePunchRect.y(), m_holePunchRect.width(), m_holePunchRect.height());
#endif
setNeedsCommit();
}
@@ -95,7 +95,7 @@ void VideoLayerWebKitThread::boundsChanged()
m_holePunchClipRect = holePunchRect();
#if DEBUG_VIDEO_CLIPPING
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "VideoLayerWebKitThread m_holePunchClipRect=(x=%d,y=%d,width=%d,height=%d).", m_holePunchClipRect.x(), m_holePunchClipRect.y(), m_holePunchClipRect.width(), m_holePunchClipRect.height());
+ BBLOG(BlackBerry::Platform::LogLevelInfo, "VideoLayerWebKitThread m_holePunchClipRect=(x=%d,y=%d,width=%d,height=%d).", m_holePunchClipRect.x(), m_holePunchClipRect.y(), m_holePunchClipRect.width(), m_holePunchClipRect.height());
#endif
}
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
index dcdb586d0..3ec8343a9 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
@@ -32,10 +32,12 @@
#include "Animation.h"
#include "FloatConversion.h"
#include "FloatRect.h"
+#include "GraphicsLayerFactory.h"
#include "PlatformCALayer.h"
#include "RotateTransformOperation.h"
#include "ScaleTransformOperation.h"
#include "SystemTime.h"
+#include "TextStream.h"
#include "TransformState.h"
#include "TranslateTransformOperation.h"
#include <QuartzCore/CATransform3D.h>
@@ -255,6 +257,14 @@ static inline bool supportsAcceleratedFilterAnimations()
}
#endif
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
+{
+ if (!factory)
+ return adoptPtr(new GraphicsLayerCA(client));
+
+ return factory->createGraphicsLayer(client);
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return adoptPtr(new GraphicsLayerCA(client));
@@ -265,12 +275,13 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
, m_contentsLayerPurpose(NoContentsLayer)
, m_contentsLayerHasBackgroundColor(false)
, m_allowTiledLayer(true)
+ , m_isPageTileCacheLayer(false)
, m_uncommittedChanges(0)
{
PlatformCALayer::LayerType layerType = PlatformCALayer::LayerTypeWebLayer;
if (client && client->shouldUseTileCache(this)) {
- layerType = PlatformCALayer::LayerTypeTileCacheLayer;
- m_usingTileCache = true;
+ layerType = PlatformCALayer::LayerTypePageTileCacheLayer;
+ m_isPageTileCacheLayer = true;
}
m_layer = PlatformCALayer::create(layerType, this);
@@ -477,7 +488,7 @@ void GraphicsLayerCA::moveOrCopyAnimations(MoveOrCopy operation, PlatformCALayer
// Look for running animations affecting this property.
AnimationsMap::const_iterator end = m_runningAnimations.end();
for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
- const Vector<LayerPropertyAnimation>& propertyAnimations = it->second;
+ const Vector<LayerPropertyAnimation>& propertyAnimations = it->value;
size_t numAnimations = propertyAnimations.size();
for (size_t i = 0; i < numAnimations; ++i) {
const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
@@ -719,7 +730,7 @@ void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOff
AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
if (it != m_animationsToProcess.end()) {
- AnimationProcessingAction& processingInfo = it->second;
+ AnimationProcessingAction& processingInfo = it->value;
// If an animation is scheduled to be removed, don't change the remove to a pause.
if (processingInfo.action != Remove)
processingInfo.action = Pause;
@@ -854,7 +865,7 @@ void GraphicsLayerCA::layerDidDisplay(PlatformLayer* layer)
if (layerCloneMap) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- PlatformCALayer* currClone = it->second.get();
+ PlatformCALayer* currClone = it->value.get();
if (!currClone)
continue;
@@ -884,13 +895,13 @@ FloatPoint GraphicsLayerCA::computePositionRelativeToBase(float& pageScale) cons
return FloatPoint();
}
-void GraphicsLayerCA::syncCompositingState(const FloatRect& clipRect)
+void GraphicsLayerCA::flushCompositingState(const FloatRect& clipRect)
{
TransformState state(TransformState::UnapplyInverseTransformDirection, FloatQuad(clipRect));
recursiveCommitChanges(state);
}
-void GraphicsLayerCA::syncCompositingStateForThisLayerOnly()
+void GraphicsLayerCA::flushCompositingStateForThisLayerOnly()
{
float pageScaleFactor;
FloatPoint offset = computePositionRelativeToBase(pageScaleFactor);
@@ -903,44 +914,72 @@ TiledBacking* GraphicsLayerCA::tiledBacking()
return m_layer->tiledBacking();
}
-void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
+void GraphicsLayerCA::computeVisibleRect(TransformState& state)
{
- // Save the state before sending down to kids and restore it after
- TransformState localState = state;
-
- TransformState::TransformAccumulation accumulation = preserves3D() ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
- localState.move(m_position.x(), m_position.y(), accumulation);
+ bool preserve3D = preserves3D() || (parent() ? parent()->preserves3D() : false);
+ TransformState::TransformAccumulation accumulation = preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform;
+
+ TransformationMatrix layerTransform;
+ layerTransform.translate(m_position.x(), m_position.y());
if (!transform().isIdentity()) {
- TransformationMatrix transformWithAnchorPoint;
FloatPoint3D absoluteAnchorPoint(anchorPoint());
absoluteAnchorPoint.scale(size().width(), size().height(), 1);
- transformWithAnchorPoint.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
- transformWithAnchorPoint.multiply(transform());
- transformWithAnchorPoint.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
- localState.applyTransform(transformWithAnchorPoint, accumulation);
+ layerTransform.translate3d(absoluteAnchorPoint.x(), absoluteAnchorPoint.y(), absoluteAnchorPoint.z());
+ layerTransform.multiply(transform());
+ layerTransform.translate3d(-absoluteAnchorPoint.x(), -absoluteAnchorPoint.y(), -absoluteAnchorPoint.z());
+ }
+
+ if (GraphicsLayer* parentLayer = parent()) {
+ if (!parentLayer->childrenTransform().isIdentity()) {
+ FloatPoint3D parentAnchorPoint(parentLayer->anchorPoint());
+ parentAnchorPoint.scale(parentLayer->size().width(), parentLayer->size().height(), 1);
+
+ layerTransform.translateRight3d(-parentAnchorPoint.x(), -parentAnchorPoint.y(), -parentAnchorPoint.z());
+ layerTransform = parentLayer->childrenTransform() * layerTransform;
+ layerTransform.translateRight3d(parentAnchorPoint.x(), parentAnchorPoint.y(), parentAnchorPoint.z());
+ }
}
+
+ state.applyTransform(layerTransform, accumulation);
- FloatRect clipRectForChildren = localState.lastPlanarQuad().boundingBox();
- FloatRect clipRectForSelf;
+ FloatRect clipRectForChildren = state.mappedQuad().boundingBox();
+ FloatRect clipRectForSelf(0, 0, m_size.width(), m_size.height());
+ clipRectForSelf.intersect(clipRectForChildren);
if (masksToBounds()) {
ASSERT(accumulation == TransformState::FlattenTransform);
-
// Replace the quad in the TransformState with one that is clipped to this layer's bounds
- clipRectForSelf = FloatRect(0, 0, m_size.width(), m_size.height());
- clipRectForSelf.intersect(clipRectForChildren);
- localState.setQuad(clipRectForSelf);
+ state.setQuad(clipRectForSelf);
}
+ m_visibleRect = clipRectForSelf;
+}
+
+void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
+{
+ TransformState localState = state;
+ computeVisibleRect(localState);
+
#ifdef VISIBLE_TILE_WASH
- if (m_visibleTileWashLayer) {
- if (clipRectForSelf.isEmpty()) {
- clipRectForSelf = FloatRect(0, 0, m_size.width(), m_size.height());
- clipRectForSelf.intersect(clipRectForChildren);
- }
- m_visibleTileWashLayer->setFrame(clipRectForSelf);
+ // Use having a transform as a key to making the tile wash layer. If every layer gets a wash,
+ // they start to obscure useful information.
+ if ((!m_transform.isIdentity() || m_usingTiledLayer) && !m_visibleTileWashLayer) {
+ static Color washFillColor(255, 0, 0, 50);
+ static Color washBorderColor(255, 0, 0, 100);
+
+ m_visibleTileWashLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
+ String name = String::format("Visible Tile Wash Layer %p", m_visibleTileWashLayer->platformLayer());
+ m_visibleTileWashLayer->setName(name);
+ m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
+ m_visibleTileWashLayer->setBorderColor(washBorderColor);
+ m_visibleTileWashLayer->setBorderWidth(8);
+ m_visibleTileWashLayer->setBackgroundColor(washFillColor);
+ noteSublayersChanged();
}
+
+ if (m_visibleTileWashLayer)
+ m_visibleTileWashLayer->setFrame(m_visibleRect);
#endif
bool hadChanges = m_uncommittedChanges;
@@ -963,9 +1002,6 @@ void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float
const Vector<GraphicsLayer*>& childLayers = children();
size_t numChildren = childLayers.size();
- if (!childrenTransform().isIdentity())
- localState.applyTransform(childrenTransform(), accumulation);
-
for (size_t i = 0; i < numChildren; ++i) {
GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
curChild->recursiveCommitChanges(localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
@@ -983,6 +1019,16 @@ void GraphicsLayerCA::recursiveCommitChanges(const TransformState& state, float
client()->didCommitChangesForLayer(this);
}
+bool GraphicsLayerCA::platformCALayerShowRepaintCounter(PlatformCALayer* platformLayer) const
+{
+ // The repaint counters are painted into the TileCache tiles (which have no corresponding platform layer),
+ // so we don't want to overpaint the repaint counter when called with the TileCache's own layer.
+ if (m_isPageTileCacheLayer && platformLayer)
+ return false;
+
+ return showRepaintCounter();
+}
+
void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, const IntRect& clip)
{
paintGraphicsLayerContents(context, clip);
@@ -990,14 +1036,14 @@ void GraphicsLayerCA::platformCALayerPaintContents(GraphicsContext& context, con
void GraphicsLayerCA::platformCALayerDidCreateTiles(const Vector<FloatRect>& dirtyRects)
{
- ASSERT(m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer);
+ ASSERT(m_layer->usesTileCacheLayer());
for (size_t i = 0; i < dirtyRects.size(); ++i)
setNeedsDisplayInRect(dirtyRects[i]);
// Ensure that the layout is up to date before any individual tiles are painted by telling the client
- // that it needs to sync its layer state, which will end up scheduling the layer flusher.
- client()->notifySyncRequired(this);
+ // that it needs to flush its layer state, which will end up scheduling the layer flusher.
+ client()->notifyFlushRequired(this);
}
float GraphicsLayerCA::platformCALayerDeviceScaleFactor()
@@ -1196,10 +1242,10 @@ void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& po
if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- PlatformCALayer* clone = it->second.get();
+ PlatformCALayer* clone = it->value.get();
FloatPoint clonePosition = layerPosition;
- if (m_replicaLayer && isReplicatedRootClone(it->first)) {
+ if (m_replicaLayer && isReplicatedRootClone(it->key)) {
// Maintain the special-case position for the root of a clone subtree,
// which we set up in replicatedLayerRoot().
clonePosition = positionForCloneRootLayer();
@@ -1223,10 +1269,10 @@ void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& po
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- PlatformCALayer* clone = it->second.get();
+ PlatformCALayer* clone = it->value.get();
FloatPoint clonePosition = adjustedPosition;
- if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(it->first)) {
+ if (!m_structuralLayer && m_replicaLayer && isReplicatedRootClone(it->key)) {
// Maintain the special-case position for the root of a clone subtree,
// which we set up in replicatedLayerRoot().
clonePosition = positionForCloneRootLayer();
@@ -1246,8 +1292,8 @@ void GraphicsLayerCA::updateTransform()
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- PlatformCALayer* currLayer = it->second.get();
- if (m_replicaLayer && isReplicatedRootClone(it->first)) {
+ PlatformCALayer* currLayer = it->value.get();
+ if (m_replicaLayer && isReplicatedRootClone(it->key)) {
// Maintain the special-case transform for the root of a clone subtree,
// which we set up in replicatedLayerRoot().
currLayer->setTransform(TransformationMatrix());
@@ -1264,7 +1310,7 @@ void GraphicsLayerCA::updateChildrenTransform()
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setSublayerTransform(m_childrenTransform);
+ it->value->setSublayerTransform(m_childrenTransform);
}
}
@@ -1275,7 +1321,7 @@ void GraphicsLayerCA::updateMasksToBounds()
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setMasksToBounds(m_masksToBounds);
+ it->value->setMasksToBounds(m_masksToBounds);
}
updateDebugIndicators();
@@ -1293,7 +1339,7 @@ void GraphicsLayerCA::updateContentsVisibility()
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setContents(0);
+ it->value->setContents(0);
}
}
}
@@ -1305,7 +1351,7 @@ void GraphicsLayerCA::updateContentsOpaque()
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setOpaque(m_contentsOpaque);
+ it->value->setOpaque(m_contentsOpaque);
}
}
@@ -1317,7 +1363,7 @@ void GraphicsLayerCA::updateBackfaceVisibility()
if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setDoubleSided(m_backfaceVisibility);
+ it->value->setDoubleSided(m_backfaceVisibility);
}
}
@@ -1326,7 +1372,7 @@ void GraphicsLayerCA::updateBackfaceVisibility()
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->second->setDoubleSided(m_backfaceVisibility);
+ it->value->setDoubleSided(m_backfaceVisibility);
}
}
@@ -1338,10 +1384,10 @@ void GraphicsLayerCA::updateFilters()
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second->setFilters(m_filters);
+ it->value->setFilters(m_filters);
}
}
}
@@ -1430,7 +1476,7 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose, floa
if (m_layerClones) {
LayerMap::const_iterator end = m_layerClones->end();
for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it) {
- PlatformCALayer* currLayer = it->second.get();
+ PlatformCALayer* currLayer = it->value.get();
currLayer->setPosition(point);
currLayer->setAnchorPoint(anchorPoint);
currLayer->setTransform(TransformationMatrix());
@@ -1475,7 +1521,7 @@ void GraphicsLayerCA::updateLayerDrawsContent(float pageScaleFactor, const Float
if (m_layerClones) {
LayerMap::const_iterator end = m_layerClones->end();
for (LayerMap::const_iterator it = m_layerClones->begin(); it != end; ++it)
- it->second->setContents(0);
+ it->value->setContents(0);
}
}
updateDebugIndicators();
@@ -1488,7 +1534,7 @@ void GraphicsLayerCA::updateAcceleratesDrawing()
void GraphicsLayerCA::updateLayerBackgroundColor()
{
- if (m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer) {
+ if (m_isPageTileCacheLayer) {
m_layer->setBackgroundColor(m_backgroundColor);
return;
}
@@ -1526,7 +1572,7 @@ void GraphicsLayerCA::updateContentsImage()
if (m_contentsLayerClones) {
LayerMap::const_iterator end = m_contentsLayerClones->end();
for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it)
- it->second->setContents(m_contentsLayer->contents());
+ it->value->setContents(m_contentsLayer->contents());
}
updateContentsRect();
@@ -1570,8 +1616,8 @@ void GraphicsLayerCA::updateContentsRect()
if (m_contentsLayerClones) {
LayerMap::const_iterator end = m_contentsLayerClones->end();
for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) {
- it->second->setPosition(point);
- it->second->setBounds(rect);
+ it->value->setPosition(point);
+ it->value->setBounds(rect);
}
}
}
@@ -1586,8 +1632,8 @@ void GraphicsLayerCA::updateMaskLayer()
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0;
- it->second->setMask(maskClone);
+ PlatformCALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->key).get() : 0;
+ it->value->setMask(maskClone);
}
}
}
@@ -1651,13 +1697,13 @@ void GraphicsLayerCA::updateLayerAnimations()
if (m_animationsToProcess.size()) {
AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
- const String& currAnimationName = it->first;
+ const String& currAnimationName = it->key;
AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
if (animationIt == m_runningAnimations.end())
continue;
- const AnimationProcessingAction& processingInfo = it->second;
- const Vector<LayerPropertyAnimation>& animations = animationIt->second;
+ const AnimationProcessingAction& processingInfo = it->value;
+ const Vector<LayerPropertyAnimation>& animations = animationIt->value;
for (size_t i = 0; i < animations.size(); ++i) {
const LayerPropertyAnimation& currAnimation = animations[i];
switch (processingInfo.action) {
@@ -1689,7 +1735,7 @@ void GraphicsLayerCA::updateLayerAnimations()
animations.append(pendingAnimation);
m_runningAnimations.add(pendingAnimation.m_name, animations);
} else {
- Vector<LayerPropertyAnimation>& animations = it->second;
+ Vector<LayerPropertyAnimation>& animations = it->value;
animations.append(pendingAnimation);
}
}
@@ -1714,11 +1760,11 @@ void GraphicsLayerCA::setAnimationOnLayer(PlatformCAAnimation* caAnim, AnimatedP
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
// Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second->removeAnimationForKey(animationID);
- it->second->addAnimationForKey(animationID, caAnim);
+ it->value->removeAnimationForKey(animationID);
+ it->value->addAnimationForKey(animationID, caAnim);
}
}
}
@@ -1753,10 +1799,10 @@ bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, co
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
// Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second ->removeAnimationForKey(animationID);
+ it->value->removeAnimationForKey(animationID);
}
}
return true;
@@ -1785,9 +1831,9 @@ void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
// Skip immediate replicas, since they move with the original.
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second->addAnimationForKey(animationID, newAnim.get());
+ it->value->addAnimationForKey(animationID, newAnim.get());
}
}
}
@@ -2311,8 +2357,8 @@ void GraphicsLayerCA::suspendAnimations(double time)
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- it->second->setSpeed(0);
- it->second->setTimeOffset(t);
+ it->value->setSpeed(0);
+ it->value->setTimeOffset(t);
}
}
}
@@ -2326,8 +2372,8 @@ void GraphicsLayerCA::resumeAnimations()
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- it->second->setSpeed(1);
- it->second->setTimeOffset(0);
+ it->value->setSpeed(1);
+ it->value->setTimeOffset(0);
}
}
}
@@ -2382,6 +2428,25 @@ void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
m_layer->setBackgroundColor(Color::transparent);
}
+void GraphicsLayerCA::getDebugBorderInfo(Color& color, float& width) const
+{
+ if (m_isPageTileCacheLayer) {
+ color = Color(0, 0, 128, 128); // tile cache layer: dark blue
+ width = 0.5;
+ return;
+ }
+
+ GraphicsLayer::getDebugBorderInfo(color, width);
+}
+
+void GraphicsLayerCA::dumpAdditionalProperties(TextStream& textStream, int indent, LayerTreeAsTextBehavior behavior) const
+{
+ if (behavior & LayerTreeAsTextIncludeVisibleRects) {
+ writeIndent(textStream, indent + 1);
+ textStream << "(visible rect " << m_visibleRect.x() << ", " << m_visibleRect.y() << " " << m_visibleRect.width() << " x " << m_visibleRect.height() << ")\n";
+ }
+}
+
void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
{
if (color.isValid()) {
@@ -2419,7 +2484,7 @@ FloatSize GraphicsLayerCA::constrainedSize() const
bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const
{
- if (!m_drawsContent || !m_allowTiledLayer || m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer)
+ if (!m_drawsContent || !m_allowTiledLayer || m_isPageTileCacheLayer)
return false;
// FIXME: catch zero-size height or width here (or earlier)?
@@ -2428,34 +2493,13 @@ bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const
void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float pageScaleFactor, const FloatPoint& positionRelativeToBase)
{
- ASSERT(m_layer->layerType() != PlatformCALayer::LayerTypeTileCacheLayer);
+ ASSERT(m_layer->layerType() != PlatformCALayer::LayerTypePageTileCacheLayer);
ASSERT(useTiledLayer != m_usingTiledLayer);
RefPtr<PlatformCALayer> oldLayer = m_layer;
m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this);
m_usingTiledLayer = useTiledLayer;
-#ifdef VISIBLE_TILE_WASH
- if (useTiledLayer) {
- if (!m_visibleTileWashLayer) {
- static Color washFillColor(255, 0, 0, 50);
- static Color washBorderColor(255, 0, 0, 100);
-
- m_visibleTileWashLayer = PlatformCALayer::create(PlatformCALayer::LayerTypeLayer, this);
- String name = String::format("Visible Tile Wash Layer %p", m_visibleTileWashLayer->platformLayer());
- m_visibleTileWashLayer->setName(name);
- m_visibleTileWashLayer->setAnchorPoint(FloatPoint3D(0, 0, 0));
- m_visibleTileWashLayer->setBorderColor(washBorderColor);
- m_visibleTileWashLayer->setBorderWidth(8);
- m_visibleTileWashLayer->setBackgroundColor(washFillColor);
- }
- } else {
- if (m_visibleTileWashLayer)
- m_visibleTileWashLayer->removeFromSuperlayer();
- m_visibleTileWashLayer = 0;
- }
-#endif
-
m_layer->adoptSublayers(oldLayer.get());
#ifdef VISIBLE_TILE_WASH
@@ -2537,13 +2581,13 @@ PassRefPtr<PlatformCALayer> GraphicsLayerCA::findOrMakeClone(CloneID cloneID, Pl
LayerMap::AddResult addResult = clones->add(cloneID, dummy);
if (!addResult.isNewEntry) {
// Value was not added, so it exists already.
- resultLayer = addResult.iterator->second.get();
+ resultLayer = addResult.iterator->value.get();
} else {
resultLayer = cloneLayer(sourceLayer, cloneLevel);
#ifndef NDEBUG
resultLayer->setName(String::format("Clone %d of layer %p", cloneID[0U], sourceLayer->platformLayer()));
#endif
- addResult.iterator->second = resultLayer;
+ addResult.iterator->value = resultLayer;
}
return resultLayer;
@@ -2577,7 +2621,7 @@ void GraphicsLayerCA::removeCloneLayers()
FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const
{
- // This can get called during a sync when we've just removed the m_replicaLayer.
+ // This can get called during a flush when we've just removed the m_replicaLayer.
if (!m_replicaLayer)
return FloatPoint();
@@ -2735,9 +2779,9 @@ void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
if (layerCloneMap) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second->setOpacity(m_opacity);
+ it->value->setOpacity(m_opacity);
}
}
}
@@ -2749,10 +2793,10 @@ void GraphicsLayerCA::updateOpacityOnLayer()
if (LayerMap* layerCloneMap = primaryLayerClones()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
- if (m_replicaLayer && isReplicatedRootClone(it->first))
+ if (m_replicaLayer && isReplicatedRootClone(it->key))
continue;
- it->second->setOpacity(m_opacity);
+ it->value->setOpacity(m_opacity);
}
}
@@ -2834,7 +2878,7 @@ void GraphicsLayerCA::noteSublayersChanged()
void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags)
{
if (!m_uncommittedChanges && m_client)
- m_client->notifySyncRequired(this);
+ m_client->notifyFlushRequired(this);
m_uncommittedChanges |= flags;
}
diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
index d5b4c2c61..b8da5776a 100644
--- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
+++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
@@ -38,7 +38,7 @@
#include <wtf/text/StringHash.h>
// Enable this to add a light red wash over the visible portion of Tiled Layers, as computed
-// by syncCompositingState().
+// by flushCompositingState().
// #define VISIBLE_TILE_WASH
namespace WebCore {
@@ -131,8 +131,8 @@ public:
void recursiveCommitChanges(const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
- virtual void syncCompositingState(const FloatRect&);
- virtual void syncCompositingStateForThisLayerOnly();
+ virtual void flushCompositingState(const FloatRect&);
+ virtual void flushCompositingStateForThisLayerOnly();
virtual TiledBacking* tiledBacking() OVERRIDE;
@@ -153,7 +153,7 @@ private:
virtual CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return contentsOrientation(); }
virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& clip);
virtual bool platformCALayerShowDebugBorders() const { return showDebugBorders(); }
- virtual bool platformCALayerShowRepaintCounter() const { return showRepaintCounter(); }
+ virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const;
virtual int platformCALayerIncrementRepaintCount() { return incrementRepaintCount(); }
virtual bool platformCALayerContentsOpaque() const { return contentsOpaque(); }
@@ -228,8 +228,12 @@ private:
virtual void setReplicatedByLayer(GraphicsLayer*);
+ virtual void getDebugBorderInfo(Color&, float& width) const;
+ virtual void dumpAdditionalProperties(TextStream&, int indent, LayerTreeAsTextBehavior) const;
+
void computePixelAlignment(float pixelAlignmentScale, const FloatPoint& positionRelativeToBase,
FloatPoint& position, FloatSize&, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const;
+ void computeVisibleRect(TransformState&);
// Used to track the path down the tree for replica layers.
struct ReplicaState {
@@ -391,6 +395,7 @@ private:
#ifdef VISIBLE_TILE_WASH
RefPtr<PlatformCALayer> m_visibleTileWashLayer;
#endif
+ FloatRect m_visibleRect;
enum ContentsLayerPurpose {
NoContentsLayer = 0,
@@ -403,6 +408,7 @@ private:
ContentsLayerPurpose m_contentsLayerPurpose;
bool m_contentsLayerHasBackgroundColor : 1;
bool m_allowTiledLayer : 1;
+ bool m_isPageTileCacheLayer : 1;
RetainPtr<CGImageRef> m_uncorrectedContentsImage;
RetainPtr<CGImageRef> m_pendingContentsImage;
diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
index e412a1d85..520711681 100644
--- a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
+++ b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h
@@ -60,6 +60,7 @@ public:
LayerTypeTransformLayer,
LayerTypeWebTiledLayer,
LayerTypeTileCacheLayer,
+ LayerTypePageTileCacheLayer,
LayerTypeRootLayer,
LayerTypeCustom
};
@@ -79,6 +80,8 @@ public:
PlatformLayer* platformLayer() const;
+ bool usesTileCacheLayer() const { return m_layerType == LayerTypePageTileCacheLayer || m_layerType == LayerTypeTileCacheLayer; }
+
PlatformCALayer* rootLayer() const;
// A list of sublayers that GraphicsLayerCA should maintain as the first sublayers.
diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h b/Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h
index 316606173..185d6358c 100644
--- a/Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h
+++ b/Source/WebCore/platform/graphics/ca/PlatformCALayerClient.h
@@ -52,7 +52,7 @@ public:
virtual GraphicsLayer::CompositingCoordinatesOrientation platformCALayerContentsOrientation() const = 0;
virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& inClip) = 0;
virtual bool platformCALayerShowDebugBorders() const = 0;
- virtual bool platformCALayerShowRepaintCounter() const = 0;
+ virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const = 0;
virtual int platformCALayerIncrementRepaintCount() = 0;
virtual bool platformCALayerContentsOpaque() const = 0;
diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
index d50886801..915a60be6 100644
--- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
@@ -35,6 +35,7 @@
#import "GraphicsContext.h"
#import "GraphicsLayerCA.h"
#import "LengthFunctions.h"
+#import "TiledBacking.h"
#import "WebLayer.h"
#import "WebTiledLayer.h"
#import "WebTileCacheLayer.h"
@@ -193,6 +194,7 @@ PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, Plat
layerClass = [WebTiledLayer class];
break;
case LayerTypeTileCacheLayer:
+ case LayerTypePageTileCacheLayer:
layerClass = [WebTileCacheLayer class];
break;
case LayerTypeCustom:
@@ -218,7 +220,7 @@ PlatformCALayer::PlatformCALayer(LayerType layerType, PlatformLayer* layer, Plat
[tiledLayer setContentsGravity:@"bottomLeft"];
}
- if (m_layerType == LayerTypeTileCacheLayer) {
+ if (usesTileCacheLayer()) {
m_customSublayers = adoptPtr(new PlatformCALayerList(1));
CALayer* tileCacheTileContainerLayer = [static_cast<WebTileCacheLayer *>(m_layer.get()) tileContainerLayer];
(*m_customSublayers)[0] = PlatformCALayer::create(tileCacheTileContainerLayer, 0);
@@ -238,7 +240,7 @@ PlatformCALayer::~PlatformCALayer()
// Remove the owner pointer from the delegate in case there is a pending animationStarted event.
[static_cast<WebAnimationDelegate*>(m_delegate.get()) setOwner:nil];
- if (m_layerType == LayerTypeTileCacheLayer)
+ if (usesTileCacheLayer())
[static_cast<WebTileCacheLayer *>(m_layer.get()) invalidate];
}
@@ -931,7 +933,7 @@ void PlatformCALayer::setContentsScale(float value)
TiledBacking* PlatformCALayer::tiledBacking()
{
- if (m_layerType != LayerTypeTileCacheLayer)
+ if (!usesTileCacheLayer())
return 0;
WebTileCacheLayer *tileCacheLayer = static_cast<WebTileCacheLayer *>(m_layer.get());
diff --git a/Source/WebCore/platform/graphics/ca/mac/TileCache.h b/Source/WebCore/platform/graphics/ca/mac/TileCache.h
index a7d33fbe5..76387e8aa 100644
--- a/Source/WebCore/platform/graphics/ca/mac/TileCache.h
+++ b/Source/WebCore/platform/graphics/ca/mac/TileCache.h
@@ -65,6 +65,9 @@ public:
bool acceleratesDrawing() const { return m_acceleratesDrawing; }
void setAcceleratesDrawing(bool);
+ void setTilesOpaque(bool);
+ bool tilesAreOpaque() const { return m_tilesAreOpaque; }
+
CALayer *tileContainerLayer() const { return m_tileContainerLayer.get(); }
void setTileDebugBorderWidth(float);
@@ -81,8 +84,11 @@ private:
// TiledBacking member functions.
virtual void visibleRectChanged(const IntRect&) OVERRIDE;
virtual void setIsInWindow(bool) OVERRIDE;
- virtual void setCanHaveScrollbars(bool) OVERRIDE;
+ virtual void setTileCoverage(TileCoverage) OVERRIDE;
+ virtual TileCoverage tileCoverage() const OVERRIDE { return m_tileCoverage; }
virtual void forceRepaint() OVERRIDE;
+ virtual void setScrollingPerformanceLoggingEnabled(bool flag) OVERRIDE { m_scrollingPerformanceLoggingEnabled = flag; }
+ virtual bool scrollingPerformanceLoggingEnabled() const OVERRIDE { return m_scrollingPerformanceLoggingEnabled; }
IntRect bounds() const;
@@ -115,9 +121,11 @@ private:
CGFloat m_scale;
CGFloat m_deviceScaleFactor;
+ TileCoverage m_tileCoverage;
bool m_isInWindow;
- bool m_canHaveScrollbars;
+ bool m_scrollingPerformanceLoggingEnabled;
bool m_acceleratesDrawing;
+ bool m_tilesAreOpaque;
RetainPtr<CGColorRef> m_tileDebugBorderColor;
float m_tileDebugBorderWidth;
diff --git a/Source/WebCore/platform/graphics/ca/mac/TileCache.mm b/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
index 6ba528089..b12b14d11 100644
--- a/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/TileCache.mm
@@ -57,9 +57,11 @@ TileCache::TileCache(WebTileCacheLayer* tileCacheLayer, const IntSize& tileSize)
, m_tileRevalidationTimer(this, &TileCache::tileRevalidationTimerFired)
, m_scale(1)
, m_deviceScaleFactor(1)
- , m_isInWindow(true)
- , m_canHaveScrollbars(true)
+ , m_tileCoverage(CoverageForVisibleArea)
+ , m_isInWindow(false)
+ , m_scrollingPerformanceLoggingEnabled(false)
, m_acceleratesDrawing(false)
+ , m_tilesAreOpaque(false)
, m_tileDebugBorderWidth(0)
{
[CATransaction begin];
@@ -76,7 +78,7 @@ TileCache::~TileCache()
ASSERT(isMainThread());
for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
- WebTileLayer* tileLayer = it->second.get();
+ WebTileLayer* tileLayer = it->value.get();
[tileLayer setTileCache:0];
}
}
@@ -96,7 +98,7 @@ void TileCache::tileCacheLayerBoundsChanged()
void TileCache::setNeedsDisplay()
{
for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
- [it->second.get() setNeedsDisplay];
+ [it->value.get() setNeedsDisplay];
}
void TileCache::setNeedsDisplayInRect(const IntRect& rect)
@@ -177,9 +179,9 @@ void TileCache::setScale(CGFloat scale)
revalidateTiles();
for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
- [it->second.get() setContentsScale:deviceScaleFactor];
+ [it->value.get() setContentsScale:deviceScaleFactor];
- IntRect tileRect = rectForTileIndex(it->first);
+ IntRect tileRect = rectForTileIndex(it->key);
FloatRect scaledTileRect = tileRect;
scaledTileRect.scale(1 / m_scale);
@@ -199,12 +201,25 @@ void TileCache::setAcceleratesDrawing(bool acceleratesDrawing)
m_acceleratesDrawing = acceleratesDrawing;
for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
- [it->second.get() setAcceleratesDrawing:m_acceleratesDrawing];
+ [it->value.get() setAcceleratesDrawing:m_acceleratesDrawing];
#else
UNUSED_PARAM(acceleratesDrawing);
#endif
}
+void TileCache::setTilesOpaque(bool opaque)
+{
+ if (opaque == m_tilesAreOpaque)
+ return;
+
+ m_tilesAreOpaque = opaque;
+
+ for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
+ WebTileLayer* tileLayer = it->value.get();
+ [tileLayer setOpaque:opaque];
+ }
+}
+
void TileCache::visibleRectChanged(const IntRect& visibleRect)
{
if (m_visibleRect == visibleRect)
@@ -222,18 +237,17 @@ void TileCache::setIsInWindow(bool isInWindow)
m_isInWindow = isInWindow;
if (!m_isInWindow) {
- // Schedule a timeout to drop tiles that are outside of the visible rect in 4 seconds.
const double tileRevalidationTimeout = 4;
scheduleTileRevalidation(tileRevalidationTimeout);
}
}
-void TileCache::setCanHaveScrollbars(bool canHaveScrollbars)
+void TileCache::setTileCoverage(TileCoverage coverage)
{
- if (m_canHaveScrollbars == canHaveScrollbars)
+ if (coverage == m_tileCoverage)
return;
- m_canHaveScrollbars = canHaveScrollbars;
+ m_tileCoverage = coverage;
scheduleTileRevalidation(0);
}
@@ -249,7 +263,7 @@ void TileCache::setTileDebugBorderWidth(float borderWidth)
m_tileDebugBorderWidth = borderWidth;
for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
- [it->second.get() setBorderWidth:m_tileDebugBorderWidth];
+ [it->value.get() setBorderWidth:m_tileDebugBorderWidth];
}
void TileCache::setTileDebugBorderColor(CGColorRef borderColor)
@@ -259,7 +273,7 @@ void TileCache::setTileDebugBorderColor(CGColorRef borderColor)
m_tileDebugBorderColor = borderColor;
for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
- [it->second.get() setBorderColor:m_tileDebugBorderColor.get()];
+ [it->value.get() setBorderColor:m_tileDebugBorderColor.get()];
}
IntRect TileCache::bounds() const
@@ -297,12 +311,15 @@ IntRect TileCache::tileCoverageRect() const
// If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
// Furthermore, if the page can't have scrollbars (for example if its body element has overflow:hidden) it's very unlikely that the
// page will ever be scrolled so we limit the tile coverage rect as well.
- if (m_isInWindow && m_canHaveScrollbars) {
+ if (m_isInWindow) {
// Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
// These values were chosen because it's more common to have tall pages and to scroll vertically,
// so we keep more tiles above and below the current area.
- tileCoverageRect.inflateX(tileCoverageRect.width() / 2);
- tileCoverageRect.inflateY(tileCoverageRect.height());
+ if (m_tileCoverage && CoverageForHorizontalScrolling)
+ tileCoverageRect.inflateX(tileCoverageRect.width() / 2);
+
+ if (m_tileCoverage && CoverageForVerticalScrolling)
+ tileCoverageRect.inflateY(tileCoverageRect.height());
}
return tileCoverageRect;
@@ -365,9 +382,9 @@ void TileCache::revalidateTiles()
Vector<TileIndex> tilesToRemove;
for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
- const TileIndex& tileIndex = it->first;
+ const TileIndex& tileIndex = it->key;
- WebTileLayer* tileLayer = it->second.get();
+ WebTileLayer* tileLayer = it->value.get();
if (!rectForTileIndex(tileIndex).intersects(tileCoverageRect)) {
// Remove this layer.
@@ -395,7 +412,7 @@ void TileCache::revalidateTiles()
TileIndex tileIndex(x, y);
IntRect tileRect = rectForTileIndex(tileIndex);
- RetainPtr<WebTileLayer>& tileLayer = m_tiles.add(tileIndex, 0).iterator->second;
+ RetainPtr<WebTileLayer>& tileLayer = m_tiles.add(tileIndex, 0).iterator->value;
if (!tileLayer) {
tileLayer = createTileLayer(tileRect);
[m_tileContainerLayer.get() addSublayer:tileLayer.get()];
@@ -415,7 +432,7 @@ void TileCache::revalidateTiles()
m_tileCoverageRect = IntRect();
for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
- const TileIndex& tileIndex = it->first;
+ const TileIndex& tileIndex = it->key;
m_tileCoverageRect.unite(rectForTileIndex(tileIndex));
}
@@ -439,7 +456,7 @@ RetainPtr<WebTileLayer> TileCache::createTileLayer(const IntRect& tileRect)
[layer.get() setBorderColor:m_tileDebugBorderColor.get()];
[layer.get() setBorderWidth:m_tileDebugBorderWidth];
[layer.get() setEdgeAntialiasingMask:0];
- [layer.get() setOpaque:YES];
+ [layer.get() setOpaque:m_tilesAreOpaque];
#ifndef NDEBUG
[layer.get() setName:@"Tile"];
#endif
@@ -463,7 +480,7 @@ bool TileCache::shouldShowRepaintCounters() const
if (!layerContents)
return false;
- return layerContents->platformCALayerShowRepaintCounter();
+ return layerContents->platformCALayerShowRepaintCounter(0);
}
void TileCache::drawRepaintCounter(WebTileLayer *layer, CGContextRef context)
diff --git a/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm b/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
index 72ae6fbd4..c6aab8aff 100644
--- a/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/WebTileCacheLayer.mm
@@ -78,6 +78,16 @@ using namespace WebCore;
_tileCache->tileCacheLayerBoundsChanged();
}
+- (void)setOpaque:(BOOL)opaque
+{
+ _tileCache->setTilesOpaque(opaque);
+}
+
+- (BOOL)isOpaque
+{
+ return _tileCache->tilesAreOpaque();
+}
+
- (void)setNeedsDisplay
{
_tileCache->setNeedsDisplay();
@@ -127,7 +137,8 @@ using namespace WebCore;
- (void)setBorderWidth:(CGFloat)borderWidth
{
- _tileCache->setTileDebugBorderWidth(borderWidth);
+ // Tiles adjoin, so halve the border width.
+ _tileCache->setTileDebugBorderWidth(borderWidth / 2);
}
@end
diff --git a/Source/WebCore/platform/graphics/ca/mac/WebTileLayer.mm b/Source/WebCore/platform/graphics/ca/mac/WebTileLayer.mm
index df88b623d..f81cd68c8 100644
--- a/Source/WebCore/platform/graphics/ca/mac/WebTileLayer.mm
+++ b/Source/WebCore/platform/graphics/ca/mac/WebTileLayer.mm
@@ -51,7 +51,7 @@ using namespace WebCore;
if (_tileCache) {
_tileCache->drawLayer(self, context);
- if (_tileCache->scrollingPerformanceLoggingEnabled())
+ if (static_cast<TiledBacking*>(_tileCache)->scrollingPerformanceLoggingEnabled())
[self logFilledFreshTile];
}
}
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
index 48b20d0b8..70168b210 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp
@@ -167,7 +167,7 @@ void PlatformCALayer::animationStarted(CFTimeInterval beginTime)
HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = m_animations.end();
for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = m_animations.begin(); it != end; ++it)
- it->second->setActualStartTimeIfNeeded(cacfBeginTime);
+ it->value->setActualStartTimeIfNeeded(cacfBeginTime);
if (m_owner)
m_owner->platformCALayerAnimationStarted(beginTime);
@@ -177,8 +177,8 @@ static void resubmitAllAnimations(PlatformCALayer* layer)
{
HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator end = layer->animations().end();
for (HashMap<String, RefPtr<PlatformCAAnimation> >::const_iterator it = layer->animations().begin(); it != end; ++it) {
- RetainPtr<CFStringRef> s(AdoptCF, it->first.createCFString());
- CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->second->platformAnimation());
+ RetainPtr<CFStringRef> s(AdoptCF, it->key.createCFString());
+ CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->value->platformAnimation());
}
}
@@ -328,7 +328,7 @@ PassRefPtr<PlatformCAAnimation> PlatformCALayer::animationForKey(const String& k
if (it == m_animations.end())
return 0;
- return it->second;
+ return it->value;
}
PlatformCALayer* PlatformCALayer::mask() const
diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
index de89ae1ce..c430cf284 100644
--- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
+++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp
@@ -96,7 +96,7 @@ void PlatformCALayerWinInternal::displayCallback(CACFLayerRef caLayer, CGContext
}
#endif
- if (owner()->owner()->platformCALayerShowRepaintCounter()) {
+ if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) {
FontCachePurgePreventer fontCachePurgePreventer;
String text = String::number(owner()->owner()->platformCALayerIncrementRepaintCount());
@@ -165,14 +165,14 @@ void PlatformCALayerWinInternal::setNeedsDisplay(const FloatRect* dirtyRect)
for (int i = 0; i < numTileLayers; ++i)
CACFLayerSetNeedsDisplay(tileAtIndex(i), dirtyRect ? &rect : 0);
- if (m_owner->owner() && m_owner->owner()->platformCALayerShowRepaintCounter()) {
+ if (m_owner->owner() && m_owner->owner()->platformCALayerShowRepaintCounter(m_owner)) {
CGRect layerBounds = m_owner->bounds();
CGRect indicatorRect = CGRectMake(layerBounds.origin.x, layerBounds.origin.y, 80, 25);
CACFLayerSetNeedsDisplay(tileAtIndex(0), &indicatorRect);
}
} else if (owner()->layerType() == PlatformCALayer::LayerTypeWebLayer) {
if (owner() && owner()->owner()) {
- if (owner()->owner()->platformCALayerShowRepaintCounter()) {
+ if (owner()->owner()->platformCALayerShowRepaintCounter(owner())) {
FloatRect layerBounds = owner()->bounds();
FloatRect repaintCounterRect = layerBounds;
diff --git a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
index e9fa5be8d..83fac1fda 100644
--- a/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp
@@ -97,7 +97,16 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
context->setCompositeOperation(CompositeCopy);
else
context->setCompositeOperation(op);
- context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context);
+
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ cairo_surface_t* surface = nativeImage->surface();
+ IntSize scaledSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
+ FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(srcRect, scaledSize);
+#else
+ FloatRect adjustedSrcRect(srcRect);
+#endif
+
+ context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, adjustedSrcRect, context);
context->restore();
diff --git a/Source/WebCore/platform/graphics/cairo/FontCairo.cpp b/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
index d6e43eb98..9a0fd305a 100644
--- a/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -35,9 +35,9 @@
#include "GlyphBuffer.h"
#include "Gradient.h"
#include "GraphicsContext.h"
-#include "PlatformContextCairo.h"
#include "ImageBuffer.h"
#include "Pattern.h"
+#include "PlatformContextCairo.h"
#include "ShadowBlur.h"
#include "SimpleFontData.h"
diff --git a/Source/WebCore/platform/graphics/cairo/GLContext.cpp b/Source/WebCore/platform/graphics/cairo/GLContext.cpp
index 3b804f602..2cb0ab3cc 100644
--- a/Source/WebCore/platform/graphics/cairo/GLContext.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GLContext.cpp
@@ -21,10 +21,12 @@
#if USE(OPENGL)
+#include "GLContextEGL.h"
+#include "GLContextGLX.h"
#include <wtf/MainThread.h>
-#if USE(GLX)
-#include "GLContextGLX.h"
+#if PLATFORM(X11)
+#include <X11/Xlib.h>
#endif
namespace WebCore {
@@ -36,22 +38,106 @@ GLContext* GLContext::sharingContext()
return sharing.get();
}
+#if PLATFORM(X11)
+// We do not want to call glXMakeContextCurrent using different Display pointers,
+// because it might lead to crashes in some drivers (fglrx). We use a shared display
+// pointer here.
+static Display* gSharedX11Display = 0;
+Display* GLContext::sharedX11Display()
+{
+ if (!gSharedX11Display)
+ gSharedX11Display = XOpenDisplay(0);
+ return gSharedX11Display;
+}
+
+void GLContext::cleanupSharedX11Display()
+{
+ if (!gSharedX11Display)
+ return;
+ XCloseDisplay(gSharedX11Display);
+ gSharedX11Display = 0;
+}
+#endif // PLATFORM(X11)
+
+// Because of driver bugs, exiting the program when there are active pbuffers
+// can crash the X server (this has been observed with the official Nvidia drivers).
+// We need to ensure that we clean everything up on exit. There are several reasons
+// that GraphicsContext3Ds will still be alive at exit, including user error (memory
+// leaks) and the page cache. In any case, we don't want the X server to crash.
+typedef Vector<GLContext*> ActiveContextList;
+static ActiveContextList& activeContextList()
+{
+ DEFINE_STATIC_LOCAL(ActiveContextList, activeContexts, ());
+ return activeContexts;
+}
+
+void GLContext::addActiveContext(GLContext* context)
+{
+ static bool addedAtExitHandler = false;
+ if (!addedAtExitHandler) {
+ atexit(&GLContext::cleanupActiveContextsAtExit);
+ addedAtExitHandler = true;
+ }
+ activeContextList().append(context);
+}
+
+static bool gCleaningUpAtExit = false;
+
+void GLContext::removeActiveContext(GLContext* context)
+{
+ // If we are cleaning up the context list at exit, don't bother removing the context
+ // from the list, since we don't want to modify the list while it's being iterated.
+ if (gCleaningUpAtExit)
+ return;
+
+ ActiveContextList& contextList = activeContextList();
+ size_t i = contextList.find(context);
+ if (i != notFound)
+ contextList.remove(i);
+}
+
+void GLContext::cleanupActiveContextsAtExit()
+{
+ gCleaningUpAtExit = true;
+
+ ActiveContextList& contextList = activeContextList();
+ for (size_t i = 0; i < contextList.size(); ++i)
+ delete contextList[i];
+
+#if PLATFORM(X11)
+ cleanupSharedX11Display();
+#endif
+}
+
+
+
PassOwnPtr<GLContext> GLContext::createContextForWindow(uint64_t windowHandle, GLContext* sharingContext)
{
#if USE(GLX)
- return GLContextGLX::createContext(windowHandle, sharingContext);
+ if (OwnPtr<GLContext> glxContext = GLContextGLX::createContext(windowHandle, sharingContext))
+ return glxContext.release();
+#endif
+#if USE(EGL)
+ if (OwnPtr<GLContext> eglContext = GLContextEGL::createContext(windowHandle, sharingContext))
+ return eglContext.release();
#endif
return nullptr;
}
GLContext::GLContext()
{
+ addActiveContext(this);
}
-PassOwnPtr<GLContext> GLContext::createOffscreenContext(GLContext* sharing)
+PassOwnPtr<GLContext> GLContext::createOffscreenContext(GLContext* sharingContext)
{
#if USE(GLX)
- return GLContextGLX::createContext(0, sharing);
+ if (OwnPtr<GLContext> glxContext = GLContextGLX::createContext(0, sharingContext))
+ return glxContext.release();
+#endif
+#if USE(EGL)
+ if (OwnPtr<GLContext> eglContext = GLContextEGL::createContext(0, sharingContext))
+ return eglContext.release();
#endif
return nullptr;
}
@@ -64,6 +150,7 @@ GLContext::~GLContext()
{
if (this == gCurrentContext)
gCurrentContext = 0;
+ removeActiveContext(this);
}
bool GLContext::makeContextCurrent()
diff --git a/Source/WebCore/platform/graphics/cairo/GLContext.h b/Source/WebCore/platform/graphics/cairo/GLContext.h
index c23a46cf1..1a8807222 100644
--- a/Source/WebCore/platform/graphics/cairo/GLContext.h
+++ b/Source/WebCore/platform/graphics/cairo/GLContext.h
@@ -25,6 +25,10 @@
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
+#if PLATFORM(X11)
+typedef struct _XDisplay Display;
+#endif
+
namespace WebCore {
class GLContext {
@@ -39,9 +43,19 @@ public:
virtual ~GLContext();
virtual bool makeContextCurrent();
virtual void swapBuffers() = 0;
+ virtual void waitNative() = 0;
virtual bool canRenderToDefaultFramebuffer() = 0;
virtual IntSize defaultFrameBufferSize() = 0;
+#if PLATFORM(X11)
+ static Display* sharedX11Display();
+ static void cleanupSharedX11Display();
+#endif
+
+ static void addActiveContext(GLContext*);
+ static void removeActiveContext(GLContext*);
+ static void cleanupActiveContextsAtExit();
+
#if USE(3D_GRAPHICS)
virtual PlatformGraphicsContext3D platformContext() = 0;
#endif
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
index dc12f6c5d..7033fa6da 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
@@ -30,12 +30,10 @@
#if USE(3D_GRAPHICS)
-#include "Extensions3DOpenGL.h"
#include "GraphicsContext3DPrivate.h"
#include "Image.h"
#include "ImageSource.h"
#include "NotImplemented.h"
-#include "OpenGLShims.h"
#include "PlatformContextCairo.h"
#include "RefPtrCairo.h"
#include "ShaderLang.h"
@@ -44,6 +42,13 @@
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
+#if USE(OPENGL_ES_2)
+#include "Extensions3DOpenGLES.h"
+#else
+#include "Extensions3DOpenGL.h"
+#include "OpenGLShims.h"
+#endif
+
namespace WebCore {
PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
@@ -55,7 +60,9 @@ PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attri
static bool initialized = false;
static bool success = true;
if (!initialized) {
+#if !USE(OPENGL_ES_2)
success = initializeOpenGLShims();
+#endif
initialized = true;
}
if (!success)
@@ -90,26 +97,26 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, H
::glBindTexture(GL_TEXTURE_2D, m_texture);
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
::glBindTexture(GL_TEXTURE_2D, 0);
// Create an FBO.
- ::glGenFramebuffersEXT(1, &m_fbo);
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ ::glGenFramebuffers(1, &m_fbo);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
m_boundFBO = m_fbo;
if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth))
- ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer);
+ ::glGenRenderbuffers(1, &m_depthStencilBuffer);
// Create a multisample FBO.
if (m_attrs.antialias) {
- ::glGenFramebuffersEXT(1, &m_multisampleFBO);
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO);
+ ::glGenFramebuffers(1, &m_multisampleFBO);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
m_boundFBO = m_multisampleFBO;
- ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ ::glGenRenderbuffers(1, &m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth)
- ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
+ ::glGenRenderbuffers(1, &m_multisampleDepthStencilBuffer);
}
}
@@ -129,8 +136,11 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, H
ANGLEResources.MaxDrawBuffers = 1;
m_compiler.setResources(ANGLEResources);
+#if !USE(OPENGL_ES_2)
::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
::glEnable(GL_POINT_SPRITE);
+#endif
+
::glClearColor(0, 0, 0, 0);
}
@@ -142,20 +152,15 @@ GraphicsContext3D::~GraphicsContext3D()
makeContextCurrent();
::glDeleteTextures(1, &m_texture);
if (m_attrs.antialias) {
- ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer);
+ ::glDeleteRenderbuffers(1, &m_multisampleColorBuffer);
if (m_attrs.stencil || m_attrs.depth)
- ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer);
- ::glDeleteFramebuffersEXT(1, &m_multisampleFBO);
+ ::glDeleteRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ ::glDeleteFramebuffers(1, &m_multisampleFBO);
} else {
if (m_attrs.stencil || m_attrs.depth)
- ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer);
+ ::glDeleteRenderbuffers(1, &m_depthStencilBuffer);
}
- ::glDeleteFramebuffersEXT(1, &m_fbo);
-}
-
-void GraphicsContext3D::releaseShaderCompiler()
-{
- notImplemented();
+ ::glDeleteFramebuffers(1, &m_fbo);
}
bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, Vector<uint8_t>& outputVector)
@@ -258,7 +263,11 @@ PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
bool GraphicsContext3D::isGLES2Compliant() const
{
+#if USE(OPENGL_ES_2)
+ return true;
+#else
return false;
+#endif
}
#if USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp
index d88242f96..294169e0e 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp
@@ -24,10 +24,16 @@
#include "HostWindow.h"
#include "NotImplemented.h"
-#include "OpenGLShims.h"
#include "PlatformContextCairo.h"
#include <wtf/OwnArrayPtr.h>
+#if USE(OPENGL_ES_2)
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include "OpenGLShims.h"
+#endif
+
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) && USE(TEXTURE_MAPPER_GL)
#include <texmap/TextureMapperGL.h>
#endif
@@ -125,7 +131,7 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper
m_context->makeContextCurrent();
m_context->resolveMultisamplingIfNecessary();
- glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_boundFBO);
+ ::glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_boundFBO);
if (previousActiveContext && previousActiveContext != m_glContext)
previousActiveContext->makeContextCurrent();
diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 3edbb88aa..89093d58c 100644
--- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -41,9 +41,9 @@
#include "FloatRect.h"
#include "Font.h"
#include "GraphicsContextPlatformPrivateCairo.h"
-#include "OwnPtrCairo.h"
#include "IntRect.h"
#include "NotImplemented.h"
+#include "OwnPtrCairo.h"
#include "Path.h"
#include "Pattern.h"
#include "PlatformContextCairo.h"
diff --git a/Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp b/Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
index c73dd028e..bebc4a321 100644
--- a/Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
@@ -26,8 +26,8 @@
#include "AffineTransform.h"
#include "TransformationMatrix.h"
-#include "IntRect.h"
#include "FloatRect.h"
+#include "IntRect.h"
#include <cairo.h>
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index a89ae94f5..14142f6cd 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -1130,6 +1130,32 @@ bool GraphicsContext::supportsTransparencyLayers()
return true;
}
+static void applyShadowOffsetWorkaroundIfNeeded(const GraphicsContext& context, CGFloat& xOffset, CGFloat& yOffset)
+{
+#if !PLATFORM(IOS)
+ if (context.isAcceleratedContext())
+ return;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+ if (wkCGContextDrawsWithCorrectShadowOffsets(context.platformContext()))
+ return;
+#endif
+
+ // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated
+ // to the desired integer. Also see: <rdar://problem/10056277>
+ static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
+ if (xOffset > 0)
+ xOffset += extraShadowOffset;
+ else if (xOffset < 0)
+ xOffset -= extraShadowOffset;
+
+ if (yOffset > 0)
+ yOffset += extraShadowOffset;
+ else if (yOffset < 0)
+ yOffset -= extraShadowOffset;
+#endif
+}
+
void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled())
@@ -1163,23 +1189,7 @@ void GraphicsContext::setPlatformShadow(const FloatSize& offset, float blur, con
// Extreme "blur" values can make text drawing crash or take crazy long times, so clamp
blurRadius = min(blurRadius, narrowPrecisionToCGFloat(1000.0));
-
-#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
- if (!isAcceleratedContext()) {
- // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated
- // to the desired integer. Also see: <rdar://problem/10056277>
- static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128);
- if (xOffset > 0)
- xOffset += extraShadowOffset;
- else if (xOffset < 0)
- xOffset -= extraShadowOffset;
-
- if (yOffset > 0)
- yOffset += extraShadowOffset;
- else if (yOffset < 0)
- yOffset -= extraShadowOffset;
- }
-#endif
+ applyShadowOffsetWorkaroundIfNeeded(*this, xOffset, yOffset);
// Check for an invalid color, as this means that the color was not set for the shadow
// and we should therefore just use the default shadow color.
diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 65bce5232..063efc65c 100644
--- a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -194,6 +194,18 @@ bool ImageSource::isSizeAvailable()
return result;
}
+static ImageOrientation orientationFromProperties(CFDictionaryRef imageProperties)
+{
+ ASSERT(imageProperties);
+ CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation);
+ if (!orientationProperty)
+ return DefaultImageOrientation;
+
+ int exifValue;
+ CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue);
+ return ImageOrientation::fromEXIFValue(exifValue);
+}
+
IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum shouldRespectOrientation) const
{
RetainPtr<CFDictionaryRef> properties(AdoptCF, CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata)));
@@ -209,7 +221,7 @@ IntSize ImageSource::frameSizeAtIndex(size_t index, RespectImageOrientationEnum
if (num)
CFNumberGetValue(num, kCFNumberIntType, &h);
- if ((shouldRespectOrientation == RespectImageOrientation) && orientationAtIndex(index).usesWidthAsHeight())
+ if ((shouldRespectOrientation == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight())
return IntSize(h, w);
return IntSize(w, h);
@@ -221,13 +233,7 @@ ImageOrientation ImageSource::orientationAtIndex(size_t index) const
if (!properties)
return DefaultImageOrientation;
- CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyOrientation);
- if (!orientationProperty)
- return DefaultImageOrientation;
-
- int exifValue;
- CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue);
- return ImageOrientation::fromEXIFValue(exifValue);
+ return orientationFromProperties(properties.get());
}
IntSize ImageSource::size(RespectImageOrientationEnum shouldRespectOrientation) const
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.cpp
index 1250e4e87..b89d995f1 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.cpp
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.cpp
@@ -51,6 +51,8 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(PassRefPtr<GraphicsContext3D> context,
, m_canvas(0)
, m_context(context)
, m_bytesAllocated(0)
+ , m_didRecordDrawCommand(false)
+ , m_framesPending(0)
, m_next(0)
, m_prev(0)
{
@@ -106,6 +108,16 @@ SkDeferredCanvas* Canvas2DLayerBridge::deferredCanvas()
return 0;
}
+void Canvas2DLayerBridge::limitPendingFrames()
+{
+ if (m_didRecordDrawCommand) {
+ m_framesPending++;
+ m_didRecordDrawCommand = false;
+ if (m_framesPending > 1)
+ flush();
+ }
+}
+
void Canvas2DLayerBridge::prepareForDraw()
{
ASSERT(deferredCanvas());
@@ -122,9 +134,20 @@ void Canvas2DLayerBridge::storageAllocatedForRecordingChanged(size_t bytesAlloca
Canvas2DLayerManager::get().layerAllocatedStorageChanged(this, delta);
}
+size_t Canvas2DLayerBridge::storageAllocatedForRecording()
+{
+ return deferredCanvas()->storageAllocatedForRecording();
+}
+
void Canvas2DLayerBridge::flushedDrawCommands()
{
- storageAllocatedForRecordingChanged(deferredCanvas()->storageAllocatedForRecording());
+ storageAllocatedForRecordingChanged(storageAllocatedForRecording());
+ m_framesPending = 0;
+}
+
+void Canvas2DLayerBridge::skippedPendingDrawCommands()
+{
+ flushedDrawCommands();
}
size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree)
@@ -140,7 +163,8 @@ size_t Canvas2DLayerBridge::freeMemoryIfPossible(size_t bytesToFree)
void Canvas2DLayerBridge::flush()
{
ASSERT(deferredCanvas());
- m_canvas->flush();
+ if (deferredCanvas()->hasPendingCommands())
+ m_canvas->flush();
}
SkCanvas* Canvas2DLayerBridge::skCanvas(SkDevice* device)
@@ -196,8 +220,10 @@ void Canvas2DLayerBridge::contextAcquired()
{
if (m_deferralMode == NonDeferred && !m_useDoubleBuffering)
m_layer->willModifyTexture();
- else if (m_deferralMode == Deferred)
+ else if (m_deferralMode == Deferred) {
Canvas2DLayerManager::get().layerDidDraw(this);
+ m_didRecordDrawCommand = true;
+ }
}
unsigned Canvas2DLayerBridge::backBufferTexture()
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.h
index 8199159c9..996917493 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerBridge.h
@@ -62,11 +62,14 @@ public:
virtual void prepareForDraw() OVERRIDE;
virtual void storageAllocatedForRecordingChanged(size_t) OVERRIDE;
virtual void flushedDrawCommands() OVERRIDE;
+ virtual void skippedPendingDrawCommands() OVERRIDE;
// Methods used by Canvas2DLayerManager
virtual size_t freeMemoryIfPossible(size_t); // virtual for mocking
virtual void flush(); // virtual for mocking
+ virtual size_t storageAllocatedForRecording(); // virtual for faking
size_t bytesAllocated() const {return m_bytesAllocated;}
+ void limitPendingFrames();
SkCanvas* skCanvas(SkDevice*);
WebKit::WebLayer* layer();
@@ -87,6 +90,8 @@ protected:
OwnPtr<WebKit::WebExternalTextureLayer> m_layer;
RefPtr<GraphicsContext3D> m_context;
size_t m_bytesAllocated;
+ bool m_didRecordDrawCommand;
+ int m_framesPending;
friend class WTF::DoublyLinkedListNode<Canvas2DLayerBridge>;
Canvas2DLayerBridge* m_next;
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.cpp
index 7ffadf7a9..7e7adb994 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.cpp
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.cpp
@@ -25,8 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Canvas2DLayerManager.h"
+#include <public/Platform.h>
#include <wtf/StdLibExtras.h>
+using WebKit::WebThread;
+
namespace {
enum {
DefaultMaxBytesAllocated = 64*1024*1024,
@@ -40,6 +43,7 @@ Canvas2DLayerManager::Canvas2DLayerManager()
: m_bytesAllocated(0)
, m_maxBytesAllocated(DefaultMaxBytesAllocated)
, m_targetBytesAllocated(DefaultTargetBytesAllocated)
+ , m_taskObserverActive(false)
{
}
@@ -47,6 +51,7 @@ Canvas2DLayerManager::~Canvas2DLayerManager()
{
ASSERT(!m_bytesAllocated);
ASSERT(!m_layerList.head());
+ ASSERT(!m_taskObserverActive);
}
void Canvas2DLayerManager::init(size_t maxBytesAllocated, size_t targetBytesAllocated)
@@ -62,6 +67,20 @@ Canvas2DLayerManager& Canvas2DLayerManager::get()
return manager;
}
+void Canvas2DLayerManager::willProcessTask()
+{
+}
+
+void Canvas2DLayerManager::didProcessTask()
+{
+ // Called after the script action for the current frame has been processed.
+ ASSERT(m_taskObserverActive);
+ WebKit::Platform::current()->currentThread()->removeTaskObserver(this);
+ m_taskObserverActive = false;
+ for (Canvas2DLayerBridge* layer = m_layerList.head(); layer; layer = layer->next())
+ layer->limitPendingFrames();
+}
+
void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer)
{
if (isInList(layer)) {
@@ -70,7 +89,13 @@ void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer)
m_layerList.push(layer); // Set as MRU
}
} else
- addLayerToList(layer);
+ addLayerToList(layer);
+
+ if (!m_taskObserverActive) {
+ m_taskObserverActive = true;
+ // Schedule a call to didProcessTask() after completion of the current script task.
+ WebKit::Platform::current()->currentThread()->addTaskObserver(this);
+ }
}
void Canvas2DLayerManager::addLayerToList(Canvas2DLayerBridge* layer)
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.h
index 373729b69..55d7ce455 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerManager.h
@@ -26,12 +26,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define Canvas2DLayerManager_h
#include "Canvas2DLayerBridge.h"
+#include <public/WebThread.h>
class Canvas2DLayerManagerTest;
namespace WebCore {
-class Canvas2DLayerManager {
+class Canvas2DLayerManager : public WebKit::WebThread::TaskObserver {
public:
static Canvas2DLayerManager& get();
void init(size_t maxBytesAllocated, size_t targetBytesAllocated);
@@ -48,10 +49,13 @@ private:
bool isInList(Canvas2DLayerBridge*);
void addLayerToList(Canvas2DLayerBridge*);
void removeLayerFromList(Canvas2DLayerBridge*);
+ virtual void willProcessTask() OVERRIDE;
+ virtual void didProcessTask() OVERRIDE;
size_t m_bytesAllocated;
size_t m_maxBytesAllocated;
size_t m_targetBytesAllocated;
+ bool m_taskObserverActive;
DoublyLinkedList<Canvas2DLayerBridge> m_layerList;
friend class ::Canvas2DLayerManagerTest; // for unit testing
diff --git a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
index a10956366..15341ca43 100644
--- a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
+++ b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
@@ -89,17 +89,6 @@ WTF::String hashKeyFromNSFont(NSFont* srcFont)
return WTF::String::format("%s %x", [[srcFont fontName] UTF8String], traits);
}
-ATSFontContainerRef fontContainerRefFromNSFont(NSFont* srcFont)
-{
- ATSFontRef fontRef = CTFontGetPlatformFont(toCTFontRef(srcFont), 0);
- if (!fontRef)
- return kATSFontContainerRefUnspecified;
- ATSFontContainerRef fontContainer = kATSFontContainerRefUnspecified;
- if (ATSFontGetContainer(fontRef, 0, &fontContainer) != noErr)
- return kATSFontContainerRefUnspecified;
- return fontContainer;
-}
-
// The only way we can tell that an in-process font has failed to load
// is if CTFontCopyGraphicsFont() returns the LastResort font.
bool isLastResortFont(CGFontRef cgFont)
diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
index edd6c135c..174056589 100644
--- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h
@@ -137,6 +137,15 @@ public:
virtual void pushGroupMarkerEXT(const String&);
virtual void popGroupMarkerEXT(void);
+ // Some helper methods to detect GPU functionality
+ virtual bool isNVIDIA() { return false; }
+ virtual bool isAMD() { return false; }
+ virtual bool isIntel() { return false; }
+ virtual String vendor() { return ""; }
+
+ virtual bool maySupportMultisampling() { return true; }
+ virtual bool requiresBuiltInFunctionEmulation() { return false; }
+
private:
// Instances of this class are strictly owned by the GraphicsContext3D implementation and do not
// need to be instantiated by any other code.
diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp
index 01d08645a..eba224a83 100644
--- a/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontCacheAndroid.cpp
@@ -97,20 +97,30 @@ void FontCache::platformInit()
{
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
- // FIXME: We do not use fontconfig on Android, so use simple logic for now.
- // https://bugs.webkit.org/show_bug.cgi?id=67587
- AtomicString atomicFamily("Arial");
- return getCachedFontData(getCachedFontPlatformData(font.fontDescription(), atomicFamily, DoNotRetain), DoNotRetain);
+ if (!length)
+ return 0;
+
+ SkUnichar skiaChar;
+ if (U16_IS_LEAD(characters[0])) {
+ ASSERT(length >= 2);
+ skiaChar = U16_GET_SUPPLEMENTARY(characters[0], characters[1]);
+ } else
+ skiaChar = characters[0];
+
+ SkString skiaFamilyName;
+ if (!SkGetFallbackFamilyNameForChar(skiaChar, &skiaFamilyName) || skiaFamilyName.isEmpty())
+ return 0;
+ return getCachedFontData(getCachedFontPlatformData(font.fontDescription(), AtomicString(skiaFamilyName.c_str()), DoNotRetain), DoNotRetain);
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{
DEFINE_STATIC_LOCAL(const AtomicString, serif, ("Serif"));
DEFINE_STATIC_LOCAL(const AtomicString, monospace, ("Monospace"));
diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 9f8998cda..18e304388 100644
--- a/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -223,10 +223,10 @@ static bool LookupAltName(const String& name, String& altName)
return false;
static int systemCp = ::GetACP();
- int fontCp = iter->second->codePage;
+ int fontCp = iter->value->codePage;
if ((isAscii && systemCp == fontCp) || (!isAscii && systemCp != fontCp)) {
- altName = String(iter->second->name);
+ altName = String(iter->value->name);
return true;
}
@@ -277,7 +277,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData,
HashMap<const wchar_t*, icu::UnicodeSet*>::iterator it = fontCmapCache->find(family);
if (it != fontCmapCache->end())
- return it->second->contains(character);
+ return it->value->contains(character);
HFONT hfont = fontData->hfont();
HWndDC hdc(0);
@@ -318,12 +318,12 @@ static bool fontContainsCharacter(const FontPlatformData* fontData,
}
// Tries the given font and save it |outFontFamilyName| if it succeeds.
-SimpleFontData* FontCache::fontDataFromDescriptionAndLogFont(const FontDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, wchar_t* outFontFamilyName)
+PassRefPtr<SimpleFontData> FontCache::fontDataFromDescriptionAndLogFont(const FontDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, wchar_t* outFontFamilyName)
{
- SimpleFontData* fontData = getCachedFontData(fontDescription, font.lfFaceName, false, shouldRetain);
+ RefPtr<SimpleFontData> fontData = getCachedFontData(fontDescription, font.lfFaceName, false, shouldRetain);
if (fontData)
memcpy(outFontFamilyName, font.lfFaceName, sizeof(font.lfFaceName));
- return fontData;
+ return fontData.release();
}
static LONG toGDIFontWeight(FontWeight fontWeight)
@@ -406,7 +406,7 @@ struct GetLastResortFallbackFontProcData {
const FontDescription* m_fontDescription;
FontCache::ShouldRetain m_shouldRetain;
wchar_t* m_fontName;
- SimpleFontData* m_fontData;
+ RefPtr<SimpleFontData> m_fontData;
};
static int CALLBACK getLastResortFallbackFontProc(const LOGFONT* logFont, const TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam)
@@ -423,7 +423,7 @@ void FontCache::platformInit()
// Given the desired base font, this will create a SimpleFontData for a specific
// font that can be used to render the given range of characters.
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
// FIXME: Consider passing fontDescription.dominantScript()
// to GetFallbackFamily here.
@@ -508,12 +508,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{
FontDescription::GenericFamilyType generic = description.genericFamily();
@@ -530,9 +530,9 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc
else if (generic == FontDescription::MonospaceFamily)
fontStr = courierStr;
- SimpleFontData* simpleFont = getCachedFontData(description, fontStr, false, shouldRetain);
+ RefPtr<SimpleFontData> simpleFont = getCachedFontData(description, fontStr, false, shouldRetain);
if (simpleFont)
- return simpleFont;
+ return simpleFont.release();
// Fall back to system fonts as Win Safari does because this function must
// return a valid font. Once we find a valid system font, we save its name
@@ -546,7 +546,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc
LOGFONT defaultGUILogFont;
GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont);
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, defaultGUILogFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
}
// Fall back to Non-client metrics fonts.
@@ -554,15 +554,15 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc
nonClientMetrics.cbSize = sizeof(nonClientMetrics);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, nonClientMetrics.lfMessageFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, nonClientMetrics.lfMenuFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, nonClientMetrics.lfStatusFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, nonClientMetrics.lfCaptionFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(description, shouldRetain, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
}
// Fall back to all the fonts installed in this PC. When a font has a
@@ -576,7 +576,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc
EnumFontFamilies(dc, 0, getLastResortFallbackFontProc, reinterpret_cast<LPARAM>(&procData));
if (procData.m_fontData)
- return procData.m_fontData;
+ return procData.m_fontData.release();
}
ASSERT_NOT_REACHED();
diff --git a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index df941cb90..10f1fd078 100644
--- a/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -415,7 +415,7 @@ bool getDerivedFontData(const UChar* family,
// check it against what we actually want (as is done in
// FontCacheWin.cpp)
FontDataCache::AddResult entry = fontDataCache.add(fontKey, FontData());
- derived = &entry.iterator->second;
+ derived = &entry.iterator->value;
derived->hfont = CreateFontIndirect(logfont);
// GetAscent may return kUndefinedAscent, but we still want to
// cache it so that we won't have to call CreateFontIndirect once
@@ -423,7 +423,7 @@ bool getDerivedFontData(const UChar* family,
derived->ascent = getAscent(derived->hfont);
derived->spaceGlyph = getSpaceGlyph(derived->hfont);
} else {
- derived = &iter->second;
+ derived = &iter->value;
// Last time, GetAscent failed so that only HFONT was
// cached. Try once more assuming that TryPreloadFont
// was called by a caller between calls.
diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 47c03cbe9..075749e9a 100644
--- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -49,6 +49,7 @@
#include "FloatConversion.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
+#include "GraphicsLayerFactory.h"
#include "Image.h"
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
@@ -77,6 +78,14 @@ using namespace WebKit;
namespace WebCore {
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
+{
+ if (!factory)
+ return adoptPtr(new GraphicsLayerChromium(client));
+
+ return factory->createGraphicsLayer(client);
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return adoptPtr(new GraphicsLayerChromium(client));
@@ -459,7 +468,8 @@ void GraphicsLayerChromium::setContentsRect(const IntRect& rect)
void GraphicsLayerChromium::setContentsToImage(Image* image)
{
bool childrenChanged = false;
- if (image) {
+ NativeImageSkia* nativeImage = image ? image->nativeImageForCurrentFrame() : 0;
+ if (nativeImage) {
if (m_contentsLayerPurpose != ContentsLayerForImage) {
m_imageLayer = adoptPtr(Platform::current()->compositorSupport()->createImageLayer());
registerContentsLayer(m_imageLayer->layer());
@@ -468,7 +478,6 @@ void GraphicsLayerChromium::setContentsToImage(Image* image)
m_contentsLayerPurpose = ContentsLayerForImage;
childrenChanged = true;
}
- NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame();
m_imageLayer->setBitmap(nativeImage->bitmap());
m_imageLayer->layer()->setOpaque(image->isBitmapImage() && !image->currentFrameHasAlpha());
updateContentsRect();
diff --git a/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h b/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h
index 6d49c5578..160eb0faa 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageBufferDataSkia.h
@@ -42,6 +42,8 @@ class ImageBufferData {
public:
ImageBufferData(const IntSize&);
+ void reportMemoryUsage(MemoryObjectInfo*) const;
+
OwnPtr<SkCanvas> m_canvas;
PlatformContextSkia m_platformContext;
#if USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index 579fa2860..8510dfa52 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -109,34 +109,34 @@ void SimpleFontData::platformDestroy()
{
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
LOGFONT winFont;
GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winFont);
float scaledSize = scaleFactor * fontDescription.computedSize();
winFont.lfHeight = -lroundf(scaledSize);
HFONT hfont = CreateFontIndirect(&winFont);
- return adoptPtr(new SimpleFontData(FontPlatformData(hfont, scaledSize, m_platformData.orientation()), isCustomFont(), false));
+ return SimpleFontData::create(FontPlatformData(hfont, scaledSize, m_platformData.orientation()), isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/Source/WebCore/platform/graphics/chromium/VDMXParser.cpp b/Source/WebCore/platform/graphics/chromium/VDMXParser.cpp
index bd30a978d..1d6d3d0c2 100644
--- a/Source/WebCore/platform/graphics/chromium/VDMXParser.cpp
+++ b/Source/WebCore/platform/graphics/chromium/VDMXParser.cpp
@@ -32,8 +32,7 @@
#include <stdlib.h>
#include <string.h>
-// For htons/ntohs
-#include <arpa/inet.h>
+#include <wtf/ByteOrder.h>
// Buffer helper class
//
diff --git a/Source/WebCore/platform/graphics/clutter/GraphicsContext3DClutter.cpp b/Source/WebCore/platform/graphics/clutter/GraphicsContext3DClutter.cpp
index abfbd47e6..7df1ee92d 100644
--- a/Source/WebCore/platform/graphics/clutter/GraphicsContext3DClutter.cpp
+++ b/Source/WebCore/platform/graphics/clutter/GraphicsContext3DClutter.cpp
@@ -56,11 +56,6 @@ GraphicsContext3D::~GraphicsContext3D()
notImplemented();
}
-void GraphicsContext3D::releaseShaderCompiler()
-{
- notImplemented();
-}
-
bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, Vector<uint8_t>& outputVector)
{
notImplemented();
diff --git a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
index eda14d037..104b7982b 100644
--- a/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
+++ b/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
@@ -28,11 +28,20 @@
#if USE(ACCELERATED_COMPOSITING)
#include "GraphicsLayerClutter.h"
+#include "GraphicsLayerFactory.h"
#include "NotImplemented.h"
namespace WebCore {
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
+{
+ if (!factory)
+ return adoptPtr(new GraphicsLayerClutter(client));
+
+ return factory->createGraphicsLayer(client);
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
return adoptPtr(new GraphicsLayerClutter(client));
diff --git a/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.cpp b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.cpp
new file mode 100644
index 000000000..d7232413e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.cpp
@@ -0,0 +1,109 @@
+/*
+ Copyright (C) 2009-2010 ProFUSION embedded systems
+ Copyright (C) 2009-2010 Samsung Electronics
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "CairoUtilitiesEfl.h"
+
+#include "RefPtrCairo.h"
+
+namespace WebCore {
+
+PassRefPtr<Evas_Object> evasObjectFromCairoImageSurface(Evas* canvas, cairo_surface_t* surface)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(surface, 0);
+
+ cairo_status_t status = cairo_surface_status(surface);
+ if (status != CAIRO_STATUS_SUCCESS) {
+ fprintf(stderr, "cairo surface is invalid: %s", cairo_status_to_string(status));
+ return 0;
+ }
+
+ cairo_surface_type_t type = cairo_surface_get_type(surface);
+ if (type != CAIRO_SURFACE_TYPE_IMAGE) {
+ fprintf(stderr, "unknown surface type %d, required %d (CAIRO_SURFACE_TYPE_IMAGE).",
+ type, CAIRO_SURFACE_TYPE_IMAGE);
+ return 0;
+ }
+
+ cairo_format_t format = cairo_image_surface_get_format(surface);
+ if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24) {
+ fprintf(stderr, "unknown surface format %d, expected %d or %d.",
+ format, CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_RGB24);
+ return 0;
+ }
+
+ int width = cairo_image_surface_get_width(surface);
+ int height = cairo_image_surface_get_height(surface);
+ int stride = cairo_image_surface_get_stride(surface);
+ if (width <= 0 || height <= 0 || stride <= 0) {
+ fprintf(stderr, "invalid image size %dx%d, stride=%d", width, height, stride);
+ return 0;
+ }
+
+ void* data = cairo_image_surface_get_data(surface);
+ if (!data) {
+ fprintf(stderr, "could not get source data.");
+ return 0;
+ }
+
+ RefPtr<Evas_Object> image = adoptRef(evas_object_image_filled_add(canvas));
+ if (!image) {
+ fprintf(stderr, "could not add image to canvas.");
+ return 0;
+ }
+
+ evas_object_image_colorspace_set(image.get(), EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_size_set(image.get(), width, height);
+ evas_object_image_alpha_set(image.get(), format == CAIRO_FORMAT_ARGB32);
+
+ if (evas_object_image_stride_get(image.get()) != stride) {
+ fprintf(stderr, "evas' stride %d diverges from cairo's %d.",
+ evas_object_image_stride_get(image.get()), stride);
+ return 0;
+ }
+
+ evas_object_image_data_copy_set(image.get(), data);
+
+ return image.release();
+}
+
+PassRefPtr<cairo_surface_t> createSurfaceForBackingStore(Ecore_Evas* ee)
+{
+ ASSERT(ee);
+
+ int width;
+ int height;
+ ecore_evas_geometry_get(ee, 0, 0, &width, &height);
+ ASSERT(width > 0 && height > 0);
+
+ unsigned char* buffer = static_cast<unsigned char*>(const_cast<void*>(ecore_evas_buffer_pixels_get(ee)));
+ RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32, width, height, width * 4));
+
+ cairo_status_t status = cairo_surface_status(surface.get());
+ if (status != CAIRO_STATUS_SUCCESS) {
+ EINA_LOG_ERR("Could not create cairo surface: %s", cairo_status_to_string(status));
+ return 0;
+ }
+
+ return surface;
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h
index d03fb1b75..a5cd2e2fb 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h
+++ b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h
@@ -1,5 +1,6 @@
/*
- Copyright (C) 2009-2011 Samsung Electronics
+ Copyright (C) 2009-2010 ProFUSION embedded systems
+ Copyright (C) 2009-2010 Samsung Electronics
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -17,26 +18,20 @@
Boston, MA 02110-1301, USA.
*/
-#ifndef GraphicsLayerEfl_h
-#define GraphicsLayerEfl_h
+#ifndef CairoUtilitiesEfl_h
+#define CairoUtilitiesEfl_h
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "GraphicsLayer.h"
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <cairo.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/efl/RefPtrEfl.h>
namespace WebCore {
-class GraphicsLayerEfl : public GraphicsLayer {
-public:
- GraphicsLayerEfl(GraphicsLayerClient*);
- virtual ~GraphicsLayerEfl();
-
- virtual void setNeedsDisplay();
- virtual void setNeedsDisplayInRect(const FloatRect&);
-};
-
-} // namespace WebCore
+PassRefPtr<Evas_Object> evasObjectFromCairoImageSurface(Evas* canvas, cairo_surface_t*);
+PassRefPtr<cairo_surface_t> createSurfaceForBackingStore(Ecore_Evas* ee);
-#endif // USE(ACCELERATED_COMPOSITING)
+}
-#endif // GraphicsLayerEfl_h
+#endif // CairoUtilitiesEfl_h
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
index 721d7c7be..6f1d4ca15 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DEfl.cpp
@@ -18,33 +18,134 @@
*/
#include "config.h"
+#include "GraphicsContext3D.h"
#if USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)
#include "GraphicsContext3DPrivate.h"
-
#include "ImageData.h"
#include "NotImplemented.h"
+#include "OpenGLShims.h"
+#include "PlatformContextCairo.h"
+#include <GL/glx.h>
+
+#if USE(OPENGL_ES_2)
+#include "Extensions3DOpenGLES.h"
+#else
+#include "Extensions3DOpenGL.h"
+#endif
namespace WebCore {
PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, RenderStyle renderStyle)
{
- bool renderDirectlyToEvasGLObject = (renderStyle == RenderDirectlyToHostWindow);
-
- OwnPtr<GraphicsContext3DPrivate> internal = GraphicsContext3DPrivate::create(attrs, hostWindow, renderDirectlyToEvasGLObject);
- if (!internal)
- return 0;
-
RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, renderStyle));
- context->m_private = internal.release();
- return context.release();
+ return context->m_private ? context.release() : 0;
}
GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
: m_currentWidth(0)
, m_currentHeight(0)
-{
+ , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT)
+ , m_attrs(attrs)
+ , m_texture(0)
+ , m_compositorTexture(0)
+ , m_fbo(0)
+#if USE(OPENGL_ES_2)
+ , m_depthBuffer(0)
+ , m_stencilBuffer(0)
+#endif
+ , m_depthStencilBuffer(0)
+ , m_layerComposited(false)
+ , m_internalColorFormat(0)
+ , m_boundFBO(0)
+ , m_activeTexture(GL_TEXTURE0)
+ , m_boundTexture0(0)
+ , m_multisampleFBO(0)
+ , m_multisampleDepthStencilBuffer(0)
+ , m_multisampleColorBuffer(0)
+ , m_private(adoptPtr(new GraphicsContext3DPrivate(this, hostWindow, renderStyle)))
+{
+ validateAttributes();
+
+ if (!m_private)
+ return;
+
+ static bool initializedShims = false;
+ static bool success = true;
+ if (!initializedShims) {
+ success = initializeOpenGLShims();
+ initializedShims = true;
+ }
+ if (!success) {
+ m_private = nullptr;
+ return;
+ }
+
+ if (renderStyle == RenderToCurrentGLContext) {
+ // Evas doesn't allow including gl headers and Evas_GL headers at the same time,
+ // so we need to query the current gl context/surface here instead of in GraphicsContext3DPrivate.
+ void* currentContext = (void*)glXGetCurrentContext();
+ void* currentSurface = (void*)glXGetCurrentDrawable();
+ m_private->setCurrentGLContext(currentContext, currentSurface);
+ }
+
+ if (renderStyle == RenderOffscreen) {
+ // Create buffers for the canvas FBO.
+ glGenFramebuffers(/* count */ 1, &m_fbo);
+
+ // Create a texture to render into.
+ glGenTextures(1, &m_texture);
+ glBindTexture(GraphicsContext3D::TEXTURE_2D, m_texture);
+ glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ glTexParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ glTexParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ glBindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+
+ // Create a multisample FBO.
+ if (m_attrs.antialias) {
+ glGenFramebuffers(1, &m_multisampleFBO);
+ glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+ m_boundFBO = m_multisampleFBO;
+ glGenRenderbuffers(1, &m_multisampleColorBuffer);
+ if (m_attrs.stencil || m_attrs.depth)
+ glGenRenderbuffers(1, &m_multisampleDepthStencilBuffer);
+ } else {
+ // Bind canvas FBO.
+ glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+ m_boundFBO = m_fbo;
+#if USE(OPENGL_ES_2)
+ if (m_attrs.depth)
+ glGenRenderbuffers(1, &m_depthBuffer);
+ if (m_context->m_attrs.stencil)
+ glGenRenderbuffers(1, &m_stencilBuffer);
+#endif
+ if (m_attrs.stencil || m_attrs.depth)
+ glGenRenderbuffers(1, &m_depthStencilBuffer);
+ }
+ }
+
+ // ANGLE initialization.
+ ShBuiltInResources ANGLEResources;
+ ShInitBuiltInResources(&ANGLEResources);
+
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.MaxVertexAttribs);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.MaxVertexUniformVectors);
+ getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.MaxVaryingVectors);
+ getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxVertexTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxCombinedTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.MaxTextureImageUnits);
+ getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.MaxFragmentUniformVectors);
+
+ // Always set to 1 for OpenGL ES.
+ ANGLEResources.MaxDrawBuffers = 1;
+ m_compiler.setResources(ANGLEResources);
+
+#if !USE(OPENGL_ES_2)
+ glEnable(GL_POINT_SPRITE);
+ glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+#endif
}
GraphicsContext3D::~GraphicsContext3D()
@@ -59,768 +160,74 @@ PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D()
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* GraphicsContext3D::platformLayer() const
{
+#if USE(TEXTURE_MAPPER_GL)
+ return m_private.get();
+#else
notImplemented();
return 0;
+#endif
}
#endif
bool GraphicsContext3D::makeContextCurrent()
{
- return m_private->makeContextCurrent();
-}
-
-bool GraphicsContext3D::isGLES2Compliant() const
-{
- return m_private->isGLES2Compliant();
-}
-
-void GraphicsContext3D::activeTexture(GC3Denum texture)
-{
- m_private->activeTexture(texture);
-}
-
-void GraphicsContext3D::attachShader(Platform3DObject program, Platform3DObject shader)
-{
- m_private->attachShader(program, shader);
-}
-
-void GraphicsContext3D::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
-{
- m_private->bindAttribLocation(program, index, name);
-}
-
-void GraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer)
-{
- m_private->bindBuffer(target, buffer);
-}
-
-void GraphicsContext3D::bindFramebuffer(GC3Denum target, Platform3DObject buffer)
-{
- m_private->bindFramebuffer(target, buffer);
-}
-
-void GraphicsContext3D::bindRenderbuffer(GC3Denum target, Platform3DObject renderbuffer)
-{
- m_private->bindRenderbuffer(target, renderbuffer);
-}
-
-void GraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture)
-{
- m_private->bindTexture(target, texture);
-}
-
-void GraphicsContext3D::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
-{
- m_private->blendColor(red, green, blue, alpha);
-}
-
-void GraphicsContext3D::blendEquation(GC3Denum mode)
-{
- m_private->blendEquation(mode);
-}
-
-void GraphicsContext3D::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- m_private->blendEquationSeparate(modeRGB, modeAlpha);
-}
-
-void GraphicsContext3D::blendFunc(GC3Denum srcFactor, GC3Denum dstFactor)
-{
- m_private->blendFunc(srcFactor, dstFactor);
-}
-
-void GraphicsContext3D::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- m_private->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage)
-{
- m_private->bufferData(target, size, 0, usage);
-}
-
-void GraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
-{
- m_private->bufferData(target, size, data, usage);
-}
-
-void GraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
-{
- m_private->bufferSubData(target, offset, size, data);
-}
-
-GC3Denum GraphicsContext3D::checkFramebufferStatus(GC3Denum target)
-{
- return m_private->checkFramebufferStatus(target);
-}
-
-void GraphicsContext3D::clear(GC3Dbitfield mask)
-{
- m_private->clear(mask);
-}
-
-void GraphicsContext3D::clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
-{
- m_private->clearColor(red, green, blue, alpha);
-}
-
-void GraphicsContext3D::clearDepth(GC3Dclampf depth)
-{
- m_private->clearDepth(depth);
-}
-
-void GraphicsContext3D::clearStencil(GC3Dint clearValue)
-{
- m_private->clearStencil(clearValue);
-}
-
-void GraphicsContext3D::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- m_private->colorMask(red, green, blue, alpha);
-}
-
-void GraphicsContext3D::compileShader(Platform3DObject shader)
-{
- m_private->compileShader(shader);
-}
-
-void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- m_private->copyTexImage2D(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)
-{
- m_private->copyTexSubImage2D(target, level, xOffset, yOffset, x, y, width, height);
-}
-
-void GraphicsContext3D::cullFace(GC3Denum mode)
-{
- m_private->cullFace(mode);
-}
-
-void GraphicsContext3D::depthFunc(GC3Denum func)
-{
- m_private->depthFunc(func);
-}
-
-void GraphicsContext3D::depthMask(GC3Dboolean flag)
-{
- m_private->depthMask(flag);
-}
-
-void GraphicsContext3D::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
-{
- m_private->depthRange(zNear, zFar);
-}
-
-void GraphicsContext3D::detachShader(Platform3DObject program, Platform3DObject shader)
-{
- m_private->detachShader(program, shader);
-}
-
-void GraphicsContext3D::disable(GC3Denum cap)
-{
- m_private->disable(cap);
-}
-
-void GraphicsContext3D::disableVertexAttribArray(GC3Duint index)
-{
- m_private->disableVertexAttribArray(index);
-}
-
-void GraphicsContext3D::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- m_private->drawArrays(mode, first, count);
-}
-
-void GraphicsContext3D::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
-{
- m_private->drawElements(mode, count, type, offset);
-}
-
-void GraphicsContext3D::enable(GC3Denum cap)
-{
- m_private->enable(cap);
-}
-
-void GraphicsContext3D::enableVertexAttribArray(GC3Duint index)
-{
- m_private->enableVertexAttribArray(index);
-}
-
-void GraphicsContext3D::finish()
-{
- m_private->finish();
-}
-
-void GraphicsContext3D::flush()
-{
- m_private->flush();
-}
-
-void GraphicsContext3D::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbufferTarget, Platform3DObject buffer)
-{
- m_private->framebufferRenderbuffer(target, attachment, renderbufferTarget, buffer);
-}
-
-void GraphicsContext3D::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum texTarget, Platform3DObject texture, GC3Dint level)
-{
- m_private->framebufferTexture2D(target, attachment, texTarget, texture, level);
-}
-
-void GraphicsContext3D::frontFace(GC3Denum mode)
-{
- m_private->frontFace(mode);
-}
-
-void GraphicsContext3D::generateMipmap(GC3Denum target)
-{
- m_private->generateMipmap(target);
-}
-
-bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
-{
- return m_private->getActiveAttrib(program, index, info);
-}
-
-bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
-{
- return m_private->getActiveUniform(program, index, info);
-}
-
-void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
-{
- m_private->getAttachedShaders(program, maxCount, count, shaders);
-}
-
-int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
-{
- return m_private->getAttribLocation(program, name);
-}
-
-void GraphicsContext3D::getBooleanv(GC3Denum paramName, GC3Dboolean* value)
-{
- m_private->getBooleanv(paramName, value);
-}
-
-void GraphicsContext3D::getBufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getBufferParameteriv(target, paramName, value);
-}
-
-GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
-{
- return m_private->getContextAttributes();
-}
-
-GC3Denum GraphicsContext3D::getError()
-{
- return m_private->getError();
-}
-
-void GraphicsContext3D::getFloatv(GC3Denum paramName, GC3Dfloat* value)
-{
- m_private->getFloatv(paramName, value);
-}
-
-void GraphicsContext3D::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getFramebufferAttachmentParameteriv(target, attachment, paramName, value);
-}
-
-void GraphicsContext3D::getIntegerv(GC3Denum paramName, GC3Dint* value)
-{
- m_private->getIntegerv(paramName, value);
-}
-
-void GraphicsContext3D::getProgramiv(Platform3DObject program, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getProgramiv(program, paramName, value);
-}
-
-String GraphicsContext3D::getProgramInfoLog(Platform3DObject program)
-{
- return m_private->getProgramInfoLog(program);
-}
-
-void GraphicsContext3D::getRenderbufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getRenderbufferParameteriv(target, paramName, value);
-}
-
-void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getShaderiv(shader, paramName, value);
-}
-
-String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
-{
- return m_private->getShaderInfoLog(shader);
-}
-
-String GraphicsContext3D::getShaderSource(Platform3DObject shader)
-{
- return m_private->getShaderSource(shader);
-}
-
-String GraphicsContext3D::getString(GC3Denum name)
-{
- return m_private->getString(name);
-}
-
-void GraphicsContext3D::getTexParameterfv(GC3Denum target, GC3Denum paramName, GC3Dfloat* value)
-{
- m_private->getTexParameterfv(target, paramName, value);
-}
-
-void GraphicsContext3D::getTexParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getTexParameteriv(target, paramName, value);
-}
-
-void GraphicsContext3D::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
-{
- m_private->getUniformfv(program, location, value);
-}
-
-void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
-{
- m_private->getUniformiv(program, location, value);
-}
-
-GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name)
-{
- return m_private->getUniformLocation(program, name);
-}
-
-void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum paramName, GC3Dfloat* value)
-{
- m_private->getVertexAttribfv(index, paramName, value);
-}
-
-void GraphicsContext3D::getVertexAttribiv(GC3Duint index, GC3Denum paramName, GC3Dint* value)
-{
- m_private->getVertexAttribiv(index, paramName, value);
-}
-
-long GraphicsContext3D::getVertexAttribOffset(GC3Duint index, GC3Denum paramName)
-{
- return m_private->getVertexAttribOffset(index, paramName);
-}
-
-void GraphicsContext3D::hint(GC3Denum target, GC3Denum mode)
-{
- m_private->hint(target, mode);
-}
-
-GC3Dboolean GraphicsContext3D::isBuffer(Platform3DObject obj)
-{
- return m_private->isBuffer(obj);
-}
-
-GC3Dboolean GraphicsContext3D::isEnabled(GC3Denum cap)
-{
- return m_private->isEnabled(cap);
-}
-
-GC3Dboolean GraphicsContext3D::isFramebuffer(Platform3DObject obj)
-{
- return m_private->isFramebuffer(obj);
-}
-
-GC3Dboolean GraphicsContext3D::isProgram(Platform3DObject obj)
-{
- return m_private->isProgram(obj);
-}
-
-GC3Dboolean GraphicsContext3D::isRenderbuffer(Platform3DObject obj)
-{
- return m_private->isRenderbuffer(obj);
-}
-
-GC3Dboolean GraphicsContext3D::isShader(Platform3DObject obj)
-{
- return m_private->isShader(obj);
-}
-
-GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject obj)
-{
- return m_private->isTexture(obj);
-}
-
-void GraphicsContext3D::lineWidth(GC3Dfloat width)
-{
- m_private->lineWidth(width);
-}
-
-void GraphicsContext3D::linkProgram(Platform3DObject program)
-{
- m_private->linkProgram(program);
-}
-
-void GraphicsContext3D::pixelStorei(GC3Denum paramName, GC3Dint param)
-{
- m_private->pixelStorei(paramName, param);
-}
-
-void GraphicsContext3D::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- m_private->polygonOffset(factor, units);
-}
-
-void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
-{
- m_private->readPixels(x, y, width, height, format, type, data);
-}
-
-void GraphicsContext3D::releaseShaderCompiler()
-{
- notImplemented();
-}
-
-void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- m_private->renderbufferStorage(target, internalformat, width, height);
-}
-
-void GraphicsContext3D::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
-{
- m_private->sampleCoverage(value, invert);
-}
-
-void GraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- m_private->scissor(x, y, width, height);
-}
-
-void GraphicsContext3D::shaderSource(Platform3DObject program, const String& string)
-{
- m_private->shaderSource(program, string);
-}
-
-void GraphicsContext3D::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- m_private->stencilFunc(func, ref, mask);
-}
-
-void GraphicsContext3D::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- m_private->stencilFuncSeparate(face, func, ref, mask);
-}
-
-void GraphicsContext3D::stencilMask(GC3Duint mask)
-{
- m_private->stencilMask(mask);
-}
-
-void GraphicsContext3D::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- m_private->stencilMaskSeparate(face, mask);
-}
-
-void GraphicsContext3D::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- m_private->stencilOp(fail, zfail, zpass);
-}
-
-void GraphicsContext3D::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- m_private->stencilOpSeparate(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)
-{
- return m_private->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
-}
-
-void GraphicsContext3D::texParameterf(GC3Denum target, GC3Denum paramName, GC3Dfloat param)
-{
- m_private->texParameterf(target, paramName, param);
-}
-
-void GraphicsContext3D::texParameteri(GC3Denum target, GC3Denum paramName, GC3Dint param)
-{
- m_private->texParameteri(target, paramName, param);
-}
-
-void GraphicsContext3D::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xOffset, GC3Dint yOffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
-{
- m_private->texSubImage2D(target, level, xOffset, yOffset, width, height, format, type, pixels);
-}
-
-void GraphicsContext3D::uniform1f(GC3Dint location, GC3Dfloat x)
-{
- m_private->uniform1f(location, x);
-}
-
-void GraphicsContext3D::uniform1fv(GC3Dint location, GGC3Dsizei size, C3Dfloat* v)
-{
- m_private->uniform1fv(location, size, v);
-}
-
-void GraphicsContext3D::uniform1i(GC3Dint location, GC3Dint x)
-{
- m_private->uniform1i(location, x);
-}
-
-void GraphicsContext3D::uniform1iv(GC3Dint location, GGC3Dsizei size, C3Dint* v)
-{
- m_private->uniform1iv(location, size, v);
-}
-
-void GraphicsContext3D::uniform2f(GC3Dint location, GC3Dfloat x, float y)
-{
- m_private->uniform2f(location, x, y);
-}
-
-void GraphicsContext3D::uniform2fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* v)
-{
- m_private->uniform2fv(location, size, v);
-}
-
-void GraphicsContext3D::uniform2i(GC3Dint location, GC3Dint x, GC3Dint y)
-{
- m_private->uniform2i(location, x, y);
-}
-
-void GraphicsContext3D::uniform2iv(GC3Dint location, GC3Dsizei size, GC3Dint* v)
-{
- m_private->uniform2iv(location, size, v);
-}
-
-void GraphicsContext3D::uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- m_private->uniform3f(location, x, y, z);
-}
-
-void GraphicsContext3D::uniform3fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* v)
-{
- m_private->uniform3fv(location, size, v);
-}
-
-void GraphicsContext3D::uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z)
-{
- m_private->uniform3i(location, x, y, z);
-}
-
-void GraphicsContext3D::uniform3iv(GC3Dint location, GC3Dsizei size, GC3Dint* v)
-{
- m_private->uniform3iv(location, size, v);
-}
-
-void GraphicsContext3D::uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- m_private->uniform4f(location, x, y, z, w);
-}
-
-void GraphicsContext3D::uniform4fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* v)
-{
- m_private->uniform4fv(location, size, v);
-}
-
-void GraphicsContext3D::uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
-{
- m_private->uniform4i(location, x, y, z, w);
-}
-
-void GraphicsContext3D::uniform4iv(GC3Dint location, GC3Dsizei size, GC3Dint* v)
-{
- m_private->uniform4iv(location, size, v);
-}
-
-void GraphicsContext3D::uniformMatrix2fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- m_private->uniformMatrix2fv(location, size, transpose, value);
-}
-
-void GraphicsContext3D::uniformMatrix3fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- m_private->uniformMatrix3fv(location, size, transpose, value);
-}
-
-void GraphicsContext3D::uniformMatrix4fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- m_private->uniformMatrix4fv(location, size, transpose, value);
-}
-
-void GraphicsContext3D::useProgram(Platform3DObject program)
-{
- m_private->useProgram(program);
-}
-
-void GraphicsContext3D::validateProgram(Platform3DObject program)
-{
- m_private->validateProgram(program);
-}
-
-void GraphicsContext3D::vertexAttrib1f(GC3Duint index, GC3Dfloat x)
-{
- m_private->vertexAttrib1f(index, x);
-}
-
-void GraphicsContext3D::vertexAttrib1fv(GC3Duint index, GC3Dfloat* values)
-{
- m_private->vertexAttrib1fv(index, values);
-}
-
-void GraphicsContext3D::vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y)
-{
- m_private->vertexAttrib2f(index, x, y);
-}
+ if (!m_private)
+ return false;
-void GraphicsContext3D::vertexAttrib2fv(GC3Duint index, GC3Dfloat* values)
-{
- m_private->vertexAttrib2fv(index, values);
-}
-
-void GraphicsContext3D::vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- m_private->vertexAttrib3f(index, x, y, z);
-}
-
-void GraphicsContext3D::vertexAttrib3fv(GC3Duint index, GC3Dfloat* values)
-{
- m_private->vertexAttrib3fv(index, values);
-}
-
-void GraphicsContext3D::vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- m_private->vertexAttrib4f(index, x, y, z, w);
-}
+ if (m_renderStyle == RenderToCurrentGLContext)
+ return true;
-void GraphicsContext3D::vertexAttrib4fv(GC3Duint index, GC3Dfloat* values)
-{
- m_private->vertexAttrib4fv(index, values);
-}
-
-void GraphicsContext3D::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset)
-{
- m_private->vertexAttribPointer(index, size, type, normalized, stride, offset);
-}
-
-void GraphicsContext3D::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- m_private->viewport(x, y, width, height);
-}
-
-void GraphicsContext3D::reshape(int width, int height)
-{
- notImplemented();
-}
-
-void GraphicsContext3D::markContextChanged()
-{
- notImplemented();
-}
-
-void GraphicsContext3D::markLayerComposited()
-{
- notImplemented();
+ return m_private->makeContextCurrent();
}
-bool GraphicsContext3D::layerComposited() const
+bool GraphicsContext3D::isGLES2Compliant() const
{
- notImplemented();
+#if USE(OPENGL_ES_2)
+ return true;
+#else
return false;
+#endif
}
-void GraphicsContext3D::paintRenderingResultsToCanvas(ImageBuffer*, DrawingBuffer* drawingBuffer)
+void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
{
notImplemented();
}
-PassRefPtr<ImageData> GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer* drawingBuffer)
+void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr<ErrorMessageCallback>)
{
notImplemented();
- return 0;
-}
-
-bool GraphicsContext3D::paintCompositedResultsToCanvas(ImageBuffer*)
-{
- return false;
-}
-
-Platform3DObject GraphicsContext3D::createBuffer()
-{
- return m_private->createBuffer();
-}
-
-Platform3DObject GraphicsContext3D::createFramebuffer()
-{
- return m_private->createFramebuffer();
-}
-
-Platform3DObject GraphicsContext3D::createProgram()
-{
- return m_private->createProgram();
-}
-
-Platform3DObject GraphicsContext3D::createRenderbuffer()
-{
- return m_private->createRenderbuffer();
-}
-
-Platform3DObject GraphicsContext3D::createShader(GC3Denum type)
-{
- return m_private->createShader(type);
-}
-
-Platform3DObject GraphicsContext3D::createTexture()
-{
- return m_private->createTexture();
}
-void GraphicsContext3D::deleteBuffer(Platform3DObject buffer)
+void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context)
{
- m_private->deleteBuffer(buffer);
-}
+ if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
+ return;
-void GraphicsContext3D::deleteFramebuffer(Platform3DObject buffer)
-{
- m_private->deleteFramebuffer(buffer);
-}
+ cairo_t* cr = context->cr();
+ context->save();
-void GraphicsContext3D::deleteProgram(Platform3DObject program)
-{
- m_private->deleteProgram(program);
-}
+ RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data(
+ const_cast<unsigned char*>(imagePixels), CAIRO_FORMAT_ARGB32, imageWidth, imageHeight, imageWidth * 4));
-void GraphicsContext3D::deleteRenderbuffer(Platform3DObject buffer)
-{
- m_private->deleteRenderbuffer(buffer);
-}
+ // OpenGL keeps the pixels stored bottom up, so we need to flip the image here.
+ cairo_translate(cr, 0, imageHeight);
+ cairo_scale(cr, 1, -1);
-void GraphicsContext3D::deleteShader(Platform3DObject shader)
-{
- m_private->deleteShader(shader);
-}
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_surface(cr, imageSurface.get(), 0, 0);
+ cairo_rectangle(cr, 0, 0, canvasWidth, -canvasHeight);
-void GraphicsContext3D::deleteTexture(Platform3DObject texture)
-{
- m_private->deleteTexture(texture);
-}
-
-void GraphicsContext3D::synthesizeGLError(GC3Denum error)
-{
- m_private->synthesizeGLError(error);
+ cairo_fill(cr);
+ context->restore();
}
-Extensions3D* GraphicsContext3D::getExtensions()
-{
- return m_private->getExtensions();
-}
-
-IntSize GraphicsContext3D::getInternalFramebufferSize() const
-{
- notImplemented();
- return IntSize();
-}
-
-void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
+#if USE(GRAPHICS_SURFACE)
+void GraphicsContext3D::createGraphicsSurfaces(const IntSize& size)
{
notImplemented();
}
+#endif
bool GraphicsContext3D::getImageData(Image* image, GC3Denum format, GC3Denum type, bool premultiplyAlpha,
bool ignoreGammaAndColorProfile, Vector<uint8_t>& outputVector)
@@ -829,32 +236,6 @@ bool GraphicsContext3D::getImageData(Image* image, GC3Denum format, GC3Denum typ
return false;
}
-void GraphicsContext3D::validateAttributes()
-{
- notImplemented();
-}
-
-void GraphicsContext3D::readRenderingResults(unsigned char* pixels, int pixelsSize)
-{
- notImplemented();
-}
-
-bool GraphicsContext3D::reshapeFBOs(const IntSize&)
-{
- notImplemented();
-}
-
-void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect&)
-{
- notImplemented();
-}
-
-bool GraphicsContext3D::isResourceSafe()
-{
- notImplemented();
- return false;
-}
-
} // namespace WebCore
#endif // USE(3D_GRAPHICS)
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
index 78e6fb12a..68bd0d57b 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
@@ -20,93 +20,90 @@
#include "config.h"
#if USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)
-
#include "GraphicsContext3DPrivate.h"
+#include "GraphicsContext.h"
#include "HostWindow.h"
#include "NotImplemented.h"
-#include "PageClientEfl.h"
-
+#include <Ecore_Evas.h>
+#include <Evas_GL.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/text/CString.h>
namespace WebCore {
-PassOwnPtr<GraphicsContext3DPrivate> GraphicsContext3DPrivate::create(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, bool renderDirectlyToHostWindow)
-{
- OwnPtr<GraphicsContext3DPrivate> internal = adoptPtr(new GraphicsContext3DPrivate());
-
- if (!internal->initialize(attributes, hostWindow, renderDirectlyToHostWindow))
- return nullptr;
-
- return internal.release();
-}
-
-GraphicsContext3DPrivate::GraphicsContext3DPrivate()
- : m_boundFBO(0)
- , m_boundTexture(0)
- , m_boundArrayBuffer(0)
+GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
+ : m_context(context)
+ , m_hostWindow(hostWindow)
, m_evasGL(0)
- , m_context(0)
- , m_surface(0)
+ , m_evasGLContext(0)
+ , m_evasGLSurface(0)
+ , m_glContext(0)
+ , m_glSurface(0)
, m_api(0)
+ , m_renderStyle(renderStyle)
{
-}
-
-GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
-{
- if (!m_evasGL)
+ if (renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
return;
- if (m_surface)
- evas_gl_surface_destroy(m_evasGL, m_surface);
-
- if (m_context)
- evas_gl_context_destroy(m_evasGL, m_context);
-
- evas_gl_free(m_evasGL);
-}
+ if (m_hostWindow && m_hostWindow->platformPageClient()) {
+ // FIXME: Implement this code path for WebKit1.
+ // Get Evas object from platformPageClient and set EvasGL related members.
+ return;
+ }
-bool GraphicsContext3DPrivate::initialize(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, bool renderDirectlyToHostWindow)
-{
- PageClientEfl* pageClient = static_cast<PageClientEfl*>(hostWindow->platformPageClient());
+ // For WebKit2, we need to create a dummy ecoreEvas object for the WebProcess in order to use EvasGL APIs.
+#ifdef HAVE_ECORE_X
+ ecore_evas_init();
+ m_ecoreEvas = adoptPtr(ecore_evas_gl_x11_new(0, 0, 0, 0, 1, 1));
+ if (!m_ecoreEvas)
+ return;
+#else
+ return;
+#endif
- Evas* evas = evas_object_evas_get(pageClient->view());
+ Evas* evas = ecore_evas_get(m_ecoreEvas.get());
+ if (!evas)
+ return;
// Create a new Evas_GL object for gl rendering on efl.
m_evasGL = evas_gl_new(evas);
if (!m_evasGL)
- return false;
+ return;
// Get the API for rendering using OpenGL.
// This returns a structure that contains all the OpenGL functions we can use to render in Evas
m_api = evas_gl_api_get(m_evasGL);
if (!m_api)
- return false;
-
- Evas_GL_Context* shareContext = 0;
-
-#if USE(ACCELERATED_COMPOSITING)
- // GC3D with RenderOffscreen style for WebGL has to be shared with AC's context when AC is enabled.
- if (!renderDirectlyToHostWindow) {
- GraphicsContext3D* context = pageClient->acceleratedCompositingContext();
- if (context)
- shareContext = static_cast<Evas_GL_Context*>(context->platformGraphicsContext3D());
- }
-#endif
+ return;
// Create a context
- m_context = evas_gl_context_create(m_evasGL, shareContext);
- if (!m_context)
- return false;
+ m_evasGLContext = evas_gl_context_create(m_evasGL, 0);
+ if (!m_evasGLContext)
+ return;
// Create a surface
- if (!createSurface(pageClient, renderDirectlyToHostWindow))
- return false;
+ if (!createSurface(0, renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow))
+ return;
+
+ makeContextCurrent();
+}
+
+GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
+{
+ if (!m_evasGL)
+ return;
+
+ if (m_evasGLSurface)
+ evas_gl_surface_destroy(m_evasGL, m_evasGLSurface);
- return makeContextCurrent();
+ if (m_evasGLContext)
+ evas_gl_context_destroy(m_evasGL, m_evasGLContext);
+
+ evas_gl_free(m_evasGL);
}
+
bool GraphicsContext3DPrivate::createSurface(PageClientEfl* pageClient, bool renderDirectlyToHostWindow)
{
// If RenderStyle is RenderOffscreen, we will be rendering to a FBO,
@@ -117,8 +114,11 @@ bool GraphicsContext3DPrivate::createSurface(PageClientEfl* pageClient, bool ren
int height = 1;
// But, in case of RenderDirectlyToHostWindow, we have to render to a render target surface with the same size as our webView.
- if (renderDirectlyToHostWindow)
- evas_object_geometry_get(pageClient->view(), &x, &y, &width, &height);
+ if (renderDirectlyToHostWindow) {
+ if (!pageClient)
+ return false;
+ // FIXME: Get geometry of webView and set size of target surface.
+ }
Evas_GL_Config config = {
EVAS_GL_RGBA_8888,
@@ -128,1002 +128,48 @@ bool GraphicsContext3DPrivate::createSurface(PageClientEfl* pageClient, bool ren
};
// Create a new Evas_GL_Surface object
- m_surface = evas_gl_surface_create(m_evasGL, &config, width, height);
- if (!m_surface)
+ m_evasGLSurface = evas_gl_surface_create(m_evasGL, &config, width, height);
+ if (!m_evasGLSurface)
return false;
#if USE(ACCELERATED_COMPOSITING)
if (renderDirectlyToHostWindow) {
Evas_Native_Surface nativeSurface;
// Fill in the Native Surface information from the given Evas GL surface.
- evas_gl_native_surface_get(m_evasGL, m_surface, &nativeSurface);
+ evas_gl_native_surface_get(m_evasGL, m_evasGLSurface, &nativeSurface);
- // Create and specially set up a evas_object which act as the render targer surface.
- if (!pageClient->createEvasObjectForAcceleratedCompositing(&nativeSurface, IntRect(x, y, width, height)))
- return false;
+ // FIXME: Create and specially set up a evas_object which act as the render targer surface.
}
#endif
- return true;
-}
-
-PlatformGraphicsContext3D GraphicsContext3DPrivate::platformGraphicsContext3D() const
-{
- return m_context;
-}
-bool GraphicsContext3DPrivate::makeContextCurrent()
-{
- return evas_gl_make_current(m_evasGL, m_surface, m_context);
-}
-
-bool GraphicsContext3DPrivate::isGLES2Compliant() const
-{
return true;
}
-void GraphicsContext3DPrivate::activeTexture(GC3Denum texture)
+void GraphicsContext3DPrivate::setCurrentGLContext(void* context, void* surface)
{
- makeContextCurrent();
- m_api->glActiveTexture(texture);
-}
-
-void GraphicsContext3DPrivate::attachShader(Platform3DObject program, Platform3DObject shader)
-{
- makeContextCurrent();
- m_api->glAttachShader(program, shader);
-}
-
-void GraphicsContext3DPrivate::bindAttribLocation(Platform3DObject program, GC3Duint index, const String& name)
-{
- makeContextCurrent();
- m_api->glBindAttribLocation(program, index, name.utf8().data());
-}
-
-void GraphicsContext3DPrivate::bindBuffer(GC3Denum target, Platform3DObject buffer)
-{
- makeContextCurrent();
- m_api->glBindBuffer(target, buffer);
-
- if (target == GL_ARRAY_BUFFER)
- m_boundArrayBuffer = buffer;
-}
-
-void GraphicsContext3DPrivate::bindFramebuffer(GC3Denum target, Platform3DObject framebuffer)
-{
- makeContextCurrent();
-
- if (framebuffer != m_boundFBO) {
- m_api->glBindFramebuffer(target, framebuffer);
- m_boundFBO = framebuffer;
- }
+ m_glContext = context;
+ m_glSurface = surface;
}
-void GraphicsContext3DPrivate::bindRenderbuffer(GC3Denum target, Platform3DObject buffer)
-{
- makeContextCurrent();
- m_api->glBindRenderbuffer(target, buffer);
-}
-
-void GraphicsContext3DPrivate::bindTexture(GC3Denum target, Platform3DObject texture)
-{
- makeContextCurrent();
- m_api->glBindTexture(target, texture);
- m_boundTexture = texture;
-}
-
-void GraphicsContext3DPrivate::blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
-{
- makeContextCurrent();
- m_api->glBlendColor(red, green, blue, alpha);
-}
-
-void GraphicsContext3DPrivate::blendEquation(GC3Denum mode)
-{
- makeContextCurrent();
- m_api->glBlendEquation(mode);
-}
-
-void GraphicsContext3DPrivate::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- makeContextCurrent();
- m_api->glBlendEquationSeparate(modeRGB, modeAlpha);
-}
-
-void GraphicsContext3DPrivate::blendFunc(GC3Denum srcFactor, GC3Denum dstFactor)
-{
- makeContextCurrent();
- m_api->glBlendFunc(srcFactor, dstFactor);
-}
-
-void GraphicsContext3DPrivate::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- makeContextCurrent();
- m_api->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void GraphicsContext3DPrivate::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage)
-{
- makeContextCurrent();
- m_api->glBufferData(target, size, data, usage);
-}
-
-void GraphicsContext3DPrivate::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data)
-{
- makeContextCurrent();
- m_api->glBufferSubData(target, offset, size, data);
-}
-
-GC3Denum GraphicsContext3DPrivate::checkFramebufferStatus(GC3Denum target)
-{
- makeContextCurrent();
- return m_api->glCheckFramebufferStatus(target);
-}
-
-void GraphicsContext3DPrivate::clear(GC3Dbitfield mask)
-{
- makeContextCurrent();
- m_api->glClear(mask);
-}
-
-void GraphicsContext3DPrivate::clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha)
-{
- makeContextCurrent();
- m_api->glClearColor(red, green, blue, alpha);
-}
-
-void GraphicsContext3DPrivate::clearDepth(GC3Dclampf depth)
-{
- makeContextCurrent();
- m_api->glClearDepthf(depth);
-}
-
-void GraphicsContext3DPrivate::clearStencil(GC3Dint clearValue)
-{
- makeContextCurrent();
- m_api->glClearStencil(clearValue);
-}
-
-void GraphicsContext3DPrivate::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- makeContextCurrent();
- m_api->glColorMask(red, green, blue, alpha);
-}
-
-void GraphicsContext3DPrivate::compileShader(Platform3DObject shader)
-{
- makeContextCurrent();
- m_api->glCompileShader(shader);
-}
-
-void GraphicsContext3DPrivate::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- makeContextCurrent();
- m_api->glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
-}
-
-void GraphicsContext3DPrivate::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xOffset, GC3Dint yOffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- makeContextCurrent();
- m_api->glCopyTexSubImage2D(target, level, xOffset, yOffset, x, y, width, height);
-}
-
-void GraphicsContext3DPrivate::cullFace(GC3Denum mode)
-{
- makeContextCurrent();
- m_api->glCullFace(mode);
-}
-
-void GraphicsContext3DPrivate::depthFunc(GC3Denum func)
-{
- makeContextCurrent();
- m_api->glDepthFunc(func);
-}
-
-void GraphicsContext3DPrivate::depthMask(GC3Dboolean flag)
-{
- makeContextCurrent();
- m_api->glDepthMask(flag);
-}
-
-void GraphicsContext3DPrivate::depthRange(GC3Dclampf zNear, GC3Dclampf zFar)
-{
- makeContextCurrent();
- m_api->glDepthRangef(zNear, zFar);
-}
-
-void GraphicsContext3DPrivate::detachShader(Platform3DObject program, Platform3DObject shader)
-{
- makeContextCurrent();
- m_api->glDetachShader(program, shader);
-}
-
-void GraphicsContext3DPrivate::disable(GC3Denum cap)
-{
- makeContextCurrent();
- m_api->glDisable(cap);
-}
-
-void GraphicsContext3DPrivate::disableVertexAttribArray(GC3Duint index)
-{
- makeContextCurrent();
- m_api->glDisableVertexAttribArray(index);
-}
-
-void GraphicsContext3DPrivate::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- makeContextCurrent();
- m_api->glDrawArrays(mode, first, count);
-}
-
-void GraphicsContext3DPrivate::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset)
-{
- makeContextCurrent();
- m_api->glDrawElements(mode, count, type, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
-}
-
-void GraphicsContext3DPrivate::enable(GC3Denum cap)
-{
- makeContextCurrent();
- m_api->glEnable(cap);
-}
-
-void GraphicsContext3DPrivate::enableVertexAttribArray(GC3Duint index)
-{
- makeContextCurrent();
- m_api->glEnableVertexAttribArray(index);
-}
-
-void GraphicsContext3DPrivate::finish()
-{
- makeContextCurrent();
- m_api->glFinish();
-}
-
-void GraphicsContext3DPrivate::flush()
-{
- makeContextCurrent();
- m_api->glFlush();
-}
-
-void GraphicsContext3DPrivate::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbufferTarget, Platform3DObject renderbuffer)
-{
- makeContextCurrent();
- m_api->glFramebufferRenderbuffer(target, attachment, renderbufferTarget, renderbuffer);
-}
-
-void GraphicsContext3DPrivate::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum texTarget, Platform3DObject texture, GC3Dint level)
-{
- makeContextCurrent();
- m_api->glFramebufferTexture2D(target, attachment, texTarget, texture, level);
-}
-
-void GraphicsContext3DPrivate::frontFace(GC3Denum mode)
-{
- makeContextCurrent();
- m_api->glFrontFace(mode);
-}
-
-void GraphicsContext3DPrivate::generateMipmap(GC3Denum target)
-{
- makeContextCurrent();
- m_api->glGenerateMipmap(target);
-}
-
-bool GraphicsContext3DPrivate::getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo& info)
-{
- if (!program) {
- synthesizeGLError(GL_INVALID_VALUE);
- return false;
- }
-
- makeContextCurrent();
-
- GLint maxNameLength = 0;
- m_api->glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
- if (!maxNameLength)
- return false;
-
- OwnArrayPtr<char> name = adoptArrayPtr(new char[maxNameLength]);
- if (!name) {
- synthesizeGLError(GL_OUT_OF_MEMORY);
- return false;
- }
-
- GLsizei length = 0;
- GLint size = 0;
- GLenum type = 0;
- m_api->glGetActiveAttrib(program, index, maxNameLength, &length, &size, &type, name.get());
- if (!length)
- return false;
-
- info.name = String::fromUTF8(name.get(), length);
- info.type = type;
- info.size = size;
- return true;
-}
-
-bool GraphicsContext3DPrivate::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info)
-{
- if (!program) {
- synthesizeGLError(GL_INVALID_VALUE);
- return false;
- }
-
- makeContextCurrent();
-
- GLint maxNameLength = 0;
- m_api->glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
- if (!maxNameLength)
- return false;
-
- OwnArrayPtr<char> name = adoptArrayPtr(new char[maxNameLength]);
- if (!name) {
- synthesizeGLError(GL_OUT_OF_MEMORY);
- return false;
- }
-
- GLsizei length = 0;
- GLint size = 0;
- GLenum type = 0;
- m_api->glGetActiveUniform(program, index, maxNameLength, &length, &size, &type, name.get());
- if (!length)
- return false;
-
- info.name = String::fromUTF8(name.get(), length);
- info.type = type;
- info.size = size;
- return true;
-}
-
-void GraphicsContext3DPrivate::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders)
-{
- makeContextCurrent();
- m_api->glGetAttachedShaders(program, maxCount, count, shaders);
-}
-
-int GraphicsContext3DPrivate::getAttribLocation(Platform3DObject program, const String& name)
-{
- makeContextCurrent();
- return m_api->glGetAttribLocation(program, name.utf8().data());
-}
-
-void GraphicsContext3DPrivate::getBooleanv(GC3Denum paramName, GC3Dboolean* value)
-{
- makeContextCurrent();
- m_api->glGetBooleanv(paramName, value);
-}
-
-void GraphicsContext3DPrivate::getBufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetBufferParameteriv(target, paramName, value);
-}
-
-GraphicsContext3D::Attributes GraphicsContext3DPrivate::getContextAttributes()
-{
- return m_attributes;
-}
-
-GC3Denum GraphicsContext3DPrivate::getError()
-{
- if (!m_syntheticErrors.isEmpty()) {
- GC3Denum error = m_syntheticErrors.first();
- m_syntheticErrors.remove(m_syntheticErrors.begin());
- return error;
- }
-
- makeContextCurrent();
- return m_api->glGetError();
-}
-
-void GraphicsContext3DPrivate::getFloatv(GC3Denum paramName, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glGetFloatv(paramName, value);
-}
-
-void GraphicsContext3DPrivate::getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetFramebufferAttachmentParameteriv(target, attachment, paramName, value);
-}
-
-void GraphicsContext3DPrivate::getIntegerv(GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetIntegerv(paramName, value);
-}
-
-void GraphicsContext3DPrivate::getProgramiv(Platform3DObject program, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetProgramiv(program, paramName, value);
-}
-
-String GraphicsContext3DPrivate::getProgramInfoLog(Platform3DObject program)
-{
- makeContextCurrent();
-
- GLint logLength = 0;
- m_api->glGetProgramiv(program, GraphicsContext3D::INFO_LOG_LENGTH, &logLength);
- if (!logLength)
- return String();
-
- OwnArrayPtr<char> log = adoptArrayPtr(new char[logLength]);
- if (!log)
- return String();
-
- GLint returnedLogLength = 0;
- m_api->glGetProgramInfoLog(program, logLength, &returnedLogLength, log.get());
- ASSERT(logLength == returnedLogLength + 1);
-
- String result = String::fromUTF8(log.get(), returnedLogLength);
- return result;
-}
-
-void GraphicsContext3DPrivate::getRenderbufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetRenderbufferParameteriv(target, paramName, value);
-}
-
-void GraphicsContext3DPrivate::getShaderiv(Platform3DObject shader, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetShaderiv(shader, paramName, value);
-}
-
-String GraphicsContext3DPrivate::getShaderInfoLog(Platform3DObject shader)
-{
- makeContextCurrent();
-
- GLint logLength = 0;
- m_api->glGetShaderiv(shader, GraphicsContext3D::INFO_LOG_LENGTH, &logLength);
- if (logLength <= 1)
- return String();
-
- OwnArrayPtr<char> log = adoptArrayPtr(new char[logLength]);
- if (!log)
- return String();
-
- GLint returnedLogLength = 0;
- m_api->glGetShaderInfoLog(shader, logLength, &returnedLogLength, log.get());
- ASSERT(logLength == returnedLogLength + 1);
-
- String result = String::fromUTF8(log.get(), returnedLogLength);
- return result;
-}
-
-String GraphicsContext3DPrivate::getShaderSource(Platform3DObject shader)
-{
- makeContextCurrent();
-
- GLint logLength = 0;
- m_api->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength);
- if (logLength <= 1)
- return String();
-
- OwnArrayPtr<char> log = adoptArrayPtr(new char[logLength]);
- if (!log)
- return String();
-
- GLint returnedLogLength = 0;
- m_api->glGetShaderSource(shader, logLength, &returnedLogLength, log.get());
- ASSERT(logLength == returnedLogLength + 1);
-
- String result = String::fromUTF8(log.get(), returnedLogLength);
- return result;
-}
-
-String GraphicsContext3DPrivate::getString(GC3Denum name)
-{
- makeContextCurrent();
- return String(reinterpret_cast<const char*>(m_api->glGetString(name)));
-}
-
-void GraphicsContext3DPrivate::getTexParameterfv(GC3Denum target, GC3Denum paramName, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glGetTexParameterfv(target, paramName, value);
-}
-
-void GraphicsContext3DPrivate::getTexParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetTexParameteriv(target, paramName, value);
-}
-
-void GraphicsContext3DPrivate::getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glGetUniformfv(program, location, value);
-}
-
-void GraphicsContext3DPrivate::getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetUniformiv(program, location, value);
-}
-
-GC3Dint GraphicsContext3DPrivate::getUniformLocation(Platform3DObject program, const String& name)
-{
- makeContextCurrent();
- return m_api->glGetUniformLocation(program, name.utf8().data());
-}
-
-void GraphicsContext3DPrivate::getVertexAttribfv(GC3Duint index, GC3Denum paramName, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glGetVertexAttribfv(index, paramName, value);
-}
-
-void GraphicsContext3DPrivate::getVertexAttribiv(GC3Duint index, GC3Denum paramName, GC3Dint* value)
-{
- makeContextCurrent();
- m_api->glGetVertexAttribiv(index, paramName, value);
-}
-
-GC3Dsizeiptr GraphicsContext3DPrivate::getVertexAttribOffset(GC3Duint index, GC3Denum paramName)
-{
- makeContextCurrent();
- void* pointer = 0;
- m_api->glGetVertexAttribPointerv(index, paramName, &pointer);
- return reinterpret_cast<GC3Dsizeiptr>(pointer);
-}
-
-void GraphicsContext3DPrivate::hint(GC3Denum target, GC3Denum mode)
-{
- makeContextCurrent();
- m_api->glHint(target, mode);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isBuffer(Platform3DObject buffer)
-{
- makeContextCurrent();
- return m_api->glIsBuffer(buffer);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isEnabled(GC3Denum cap)
-{
- makeContextCurrent();
- return m_api->glIsEnabled(cap);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isFramebuffer(Platform3DObject framebuffer)
-{
- makeContextCurrent();
- return m_api->glIsFramebuffer(framebuffer);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isProgram(Platform3DObject program)
-{
- makeContextCurrent();
- return m_api->glIsProgram(program);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isRenderbuffer(Platform3DObject renderbuffer)
-{
- makeContextCurrent();
- return m_api->glIsRenderbuffer(renderbuffer);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isShader(Platform3DObject shader)
-{
- makeContextCurrent();
- return m_api->glIsShader(shader);
-}
-
-GC3Dboolean GraphicsContext3DPrivate::isTexture(Platform3DObject texture)
-{
- makeContextCurrent();
- return m_api->glIsTexture(texture);
-}
-
-void GraphicsContext3DPrivate::lineWidth(GC3Dfloat width)
-{
- makeContextCurrent();
- m_api->glLineWidth(width);
-}
-
-void GraphicsContext3DPrivate::linkProgram(Platform3DObject program)
-{
- makeContextCurrent();
- m_api->glLinkProgram(program);
-}
-
-void GraphicsContext3DPrivate::pixelStorei(GC3Denum paramName, GC3Dint param)
-{
- makeContextCurrent();
- m_api->glPixelStorei(paramName, param);
-}
-
-void GraphicsContext3DPrivate::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- makeContextCurrent();
- m_api->glPolygonOffset(factor, units);
-}
-
-void GraphicsContext3DPrivate::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
-{
- makeContextCurrent();
-
- m_api->glFlush();
- m_api->glReadPixels(x, y, width, height, format, type, data);
-}
-
-void GraphicsContext3DPrivate::renderbufferStorage(GC3Denum target, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height)
-{
- makeContextCurrent();
- m_api->glRenderbufferStorage(target, internalFormat, width, height);
-}
-
-void GraphicsContext3DPrivate::sampleCoverage(GC3Dclampf value, GC3Dboolean invert)
-{
- makeContextCurrent();
- m_api->glSampleCoverage(value, invert);
-}
-
-void GraphicsContext3DPrivate::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- makeContextCurrent();
- m_api->glScissor(x, y, width, height);
-}
-
-void GraphicsContext3DPrivate::shaderSource(Platform3DObject shader, const String& string)
-{
- makeContextCurrent();
- const char* str = string.utf8().data();
- int length = string.length();
- m_api->glShaderSource(shader, 1, &str, &length);
-}
-
-void GraphicsContext3DPrivate::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- makeContextCurrent();
- m_api->glStencilFunc(func, ref, mask);
-}
-
-void GraphicsContext3DPrivate::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- makeContextCurrent();
- m_api->glStencilFuncSeparate(face, func, ref, mask);
-}
-
-void GraphicsContext3DPrivate::stencilMask(GC3Duint mask)
-{
- makeContextCurrent();
- m_api->glStencilMask(mask);
-}
-
-void GraphicsContext3DPrivate::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- makeContextCurrent();
- m_api->glStencilMaskSeparate(face, mask);
-}
-
-void GraphicsContext3DPrivate::stencilOp(GC3Denum fail, GC3Denum zFail, GC3Denum zPass)
-{
- makeContextCurrent();
- m_api->glStencilOp(fail, zFail, zPass);
-}
-
-void GraphicsContext3DPrivate::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zFail, GC3Denum zPass)
-{
- makeContextCurrent();
- m_api->glStencilOpSeparate(face, fail, zFail, zPass);
-}
-
-bool GraphicsContext3DPrivate::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)
-{
- makeContextCurrent();
- m_api->glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- return true;
-}
-
-void GraphicsContext3DPrivate::texParameterf(GC3Denum target, GC3Denum paramName, GC3Dfloat param)
-{
- makeContextCurrent();
- m_api->glTexParameterf(target, paramName, param);
-}
-
-void GraphicsContext3DPrivate::texParameteri(GC3Denum target, GC3Denum paramName, GC3Dint param)
-{
- makeContextCurrent();
- m_api->glTexParameteri(target, paramName, param);
-}
-
-void GraphicsContext3DPrivate::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xOffset, GC3Dint yOffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels)
-{
- makeContextCurrent();
- m_api->glTexSubImage2D(target, level, xOffset, yOffset, width, height, format, type, pixels);
-}
-
-void GraphicsContext3DPrivate::uniform1f(GC3Dint location, GC3Dfloat x)
-{
- makeContextCurrent();
- m_api->glUniform1f(location, x);
-}
-
-void GraphicsContext3DPrivate::uniform1fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
-{
- makeContextCurrent();
- m_api->glUniform1fv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform1i(GC3Dint location, GC3Dint x)
-{
- makeContextCurrent();
- m_api->glUniform1i(location, x);
-}
-
-void GraphicsContext3DPrivate::uniform1iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
-{
- makeContextCurrent();
- m_api->glUniform1iv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform2f(GC3Dint location, GC3Dfloat x, GC3Dfloat y)
-{
- makeContextCurrent();
- m_api->glUniform2f(location, x, y);
-}
-
-void GraphicsContext3DPrivate::uniform2fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
-{
- makeContextCurrent();
- m_api->glUniform2fv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform2i(GC3Dint location, GC3Dint x, GC3Dint y)
-{
- makeContextCurrent();
- m_api->glUniform2i(location, x, y);
-}
-
-void GraphicsContext3DPrivate::uniform2iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
-{
- makeContextCurrent();
- m_api->glUniform2iv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- makeContextCurrent();
- m_api->glUniform3f(location, x, y, z);
-}
-
-void GraphicsContext3DPrivate::uniform3fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
-{
- makeContextCurrent();
- m_api->glUniform3fv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z)
-{
- makeContextCurrent();
- m_api->glUniform3i(location, x, y, z);
-}
-
-void GraphicsContext3DPrivate::uniform3iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
-{
- makeContextCurrent();
- m_api->glUniform3iv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- makeContextCurrent();
- m_api->glUniform4f(location, x, y, z, w);
-}
-
-void GraphicsContext3DPrivate::uniform4fv(GC3Dint location, GC3Dsizei size, GC3Dfloat* array)
-{
- makeContextCurrent();
- m_api->glUniform4fv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
-{
- makeContextCurrent();
- m_api->glUniform4i(location, x, y, z, w);
-}
-
-void GraphicsContext3DPrivate::uniform4iv(GC3Dint location, GC3Dsizei size, GC3Dint* array)
-{
- makeContextCurrent();
- m_api->glUniform4iv(location, size, array);
-}
-
-void GraphicsContext3DPrivate::uniformMatrix2fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glUniformMatrix2fv(location, size, transpose, value);
-}
-
-void GraphicsContext3DPrivate::uniformMatrix3fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glUniformMatrix3fv(location, size, transpose, value);
-}
-
-void GraphicsContext3DPrivate::uniformMatrix4fv(GC3Dint location, GC3Dsizei size, GC3Dboolean transpose, GC3Dfloat* value)
-{
- makeContextCurrent();
- m_api->glUniformMatrix4fv(location, size, transpose, value);
-}
-
-void GraphicsContext3DPrivate::useProgram(Platform3DObject program)
-{
- makeContextCurrent();
- m_api->glUseProgram(program);
-}
-
-void GraphicsContext3DPrivate::validateProgram(Platform3DObject program)
-{
- makeContextCurrent();
- m_api->glValidateProgram(program);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib1f(GC3Duint index, GC3Dfloat x)
-{
- makeContextCurrent();
- m_api->glVertexAttrib1f(index, x);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib1fv(GC3Duint index, GC3Dfloat* values)
-{
- makeContextCurrent();
- m_api->glVertexAttrib1fv(index, values);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y)
-{
- makeContextCurrent();
- m_api->glVertexAttrib2f(index, x, y);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib2fv(GC3Duint index, GC3Dfloat* values)
-{
- makeContextCurrent();
- m_api->glVertexAttrib2fv(index, values);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- makeContextCurrent();
- m_api->glVertexAttrib3f(index, x, y, z);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib3fv(GC3Duint index, GC3Dfloat* values)
-{
- makeContextCurrent();
- m_api->glVertexAttrib3fv(index, values);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- makeContextCurrent();
- m_api->glVertexAttrib4f(index, x, y, z, w);
-}
-
-void GraphicsContext3DPrivate::vertexAttrib4fv(GC3Duint index, GC3Dfloat* values)
-{
- makeContextCurrent();
- m_api->glVertexAttrib4fv(index, values);
-}
-
-void GraphicsContext3DPrivate::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset)
-{
- makeContextCurrent();
-
- if (m_boundArrayBuffer <= 0)
- return;
-
- m_api->glVertexAttribPointer(index, size, type, normalized, stride, reinterpret_cast<GLvoid*>(static_cast<intptr_t>(offset)));
-}
-
-void GraphicsContext3DPrivate::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- makeContextCurrent();
- m_api->glViewport(x, y, width, height);
-}
-
-Platform3DObject GraphicsContext3DPrivate::createBuffer()
-{
- makeContextCurrent();
- Platform3DObject buffer = 0;
- m_api->glGenBuffers(1, &buffer);
- return buffer;
-}
-
-Platform3DObject GraphicsContext3DPrivate::createFramebuffer()
-{
- makeContextCurrent();
- Platform3DObject buffer = 0;
- m_api->glGenFramebuffers(1, &buffer);
- return buffer;
-}
-
-Platform3DObject GraphicsContext3DPrivate::createProgram()
-{
- makeContextCurrent();
- return m_api->glCreateProgram();
-}
-
-Platform3DObject GraphicsContext3DPrivate::createRenderbuffer()
-{
- makeContextCurrent();
- Platform3DObject buffer;
- m_api->glGenRenderbuffers(1, &buffer);
- return buffer;
-}
-
-Platform3DObject GraphicsContext3DPrivate::createShader(GC3Denum shaderType)
-{
- makeContextCurrent();
- return m_api->glCreateShader(shaderType);
-}
-
-Platform3DObject GraphicsContext3DPrivate::createTexture()
-{
- makeContextCurrent();
- Platform3DObject texture;
- m_api->glGenTextures(1, &texture);
- return texture;
-}
-
-void GraphicsContext3DPrivate::deleteBuffer(Platform3DObject buffer)
-{
- makeContextCurrent();
- m_api->glDeleteBuffers(1, &buffer);
-}
-
-void GraphicsContext3DPrivate::deleteFramebuffer(Platform3DObject framebuffer)
-{
- makeContextCurrent();
- if (framebuffer == m_boundFBO) {
- // Make sure the framebuffer is not going to be used for drawing
- // operations after it gets deleted.
- bindFramebuffer(FRAMEBUFFER, 0);
- }
- m_api->glDeleteFramebuffers(1, &framebuffer);
-}
-
-void GraphicsContext3DPrivate::deleteProgram(Platform3DObject program)
-{
- makeContextCurrent();
- m_api->glDeleteProgram(program);
-}
-
-void GraphicsContext3DPrivate::deleteRenderbuffer(Platform3DObject renderbuffer)
-{
- makeContextCurrent();
- m_api->glDeleteRenderbuffers(1, &renderbuffer);
-}
-
-void GraphicsContext3DPrivate::deleteShader(Platform3DObject shader)
+PlatformGraphicsContext3D GraphicsContext3DPrivate::platformGraphicsContext3D() const
{
- makeContextCurrent();
- m_api->glDeleteShader(shader);
-}
+ if (m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
+ return m_glContext;
-void GraphicsContext3DPrivate::deleteTexture(Platform3DObject texture)
-{
- makeContextCurrent();
- m_api->glDeleteTextures(1, &texture);
+ return m_evasGLContext;
}
-void GraphicsContext3DPrivate::synthesizeGLError(GC3Denum error)
+bool GraphicsContext3DPrivate::makeContextCurrent()
{
- m_syntheticErrors.add(error);
+ return evas_gl_make_current(m_evasGL, m_evasGLSurface, m_evasGLContext);
}
-Extensions3D* GraphicsContext3DPrivate::getExtensions()
+#if USE(TEXTURE_MAPPER_GL)
+void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask)
{
notImplemented();
- return 0;
}
-
+#endif
} // namespace WebCore
#endif // USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
index d02b87845..08ccf77a6 100644
--- a/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
+++ b/Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
@@ -22,15 +22,26 @@
#include "GraphicsContext3D.h"
-#include <Evas_GL.h>
+#if USE(TEXTURE_MAPPER_GL)
+#include <texmap/TextureMapperPlatformLayer.h>
+#endif
-namespace WebCore {
+typedef struct _Evas_GL Evas_GL;
+typedef struct _Evas_GL_Surface Evas_GL_Surface;
+typedef struct _Evas_GL_Context Evas_GL_Context;
+typedef struct _Evas_GL_Config Evas_GL_Config;
+typedef struct _Evas_GL_API Evas_GL_API;
class PageClientEfl;
-class GraphicsContext3DPrivate {
+namespace WebCore {
+class GraphicsContext3DPrivate
+#if USE(TEXTURE_MAPPER_GL)
+ : public TextureMapperPlatformLayer
+#endif
+{
public:
- static PassOwnPtr<GraphicsContext3DPrivate> create(GraphicsContext3D::Attributes attrs, HostWindow*, bool renderDirectlyToEvasGLObject);
+ GraphicsContext3DPrivate(GraphicsContext3D*, HostWindow*, GraphicsContext3D::RenderStyle);
~GraphicsContext3DPrivate();
PlatformGraphicsContext3D platformGraphicsContext3D() const;
@@ -38,188 +49,27 @@ public:
#if USE(ACCELERATED_COMPOSITING)
PlatformLayer* platformLayer() const;
#endif
-
+#if USE(TEXTURE_MAPPER_GL)
+ virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+#endif
bool makeContextCurrent();
-
- bool isGLES2Compliant() const;
-
- void activeTexture(GC3Denum texture);
- void attachShader(Platform3DObject program, Platform3DObject shader);
- void bindAttribLocation(Platform3DObject, GC3Duint index, const String& name);
- void bindBuffer(GC3Denum target, Platform3DObject);
- void bindFramebuffer(GC3Denum target, Platform3DObject);
- void bindRenderbuffer(GC3Denum target, Platform3DObject);
- void bindTexture(GC3Denum target, Platform3DObject);
- void blendColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);
- void blendEquation(GC3Denum mode);
- void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
- void blendFunc(GC3Denum srcFactor, GC3Denum dstFactor);
- void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
-
- void bufferData(GC3Denum target, GC3Dsizeiptr, const void* data, GC3Denum usage);
- void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr, const void* data);
-
- GC3Denum checkFramebufferStatus(GC3Denum target);
- void clear(GC3Dbitfield mask);
- void clearColor(GC3Dclampf red, GC3Dclampf green, GC3Dclampf blue, GC3Dclampf alpha);
- void clearDepth(GC3Dclampf depth);
- void clearStencil(GC3Dint clearValue);
- void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
- void compileShader(Platform3DObject);
-
- 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);
- void cullFace(GC3Denum mode);
- void depthFunc(GC3Denum func);
- void depthMask(GC3Dboolean flag);
- void depthRange(GC3Dclampf zNear, GC3Dclampf zFar);
- void detachShader(Platform3DObject, Platform3DObject);
- void disable(GC3Denum cap);
- void disableVertexAttribArray(GC3Duint index);
- void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset);
-
- void enable(GC3Denum cap);
- void enableVertexAttribArray(GC3Duint index);
- void finish();
- void flush();
- void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbufferTarget, Platform3DObject);
- void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum texTarget, Platform3DObject, GC3Dint level);
- void frontFace(GC3Denum mode);
- void generateMipmap(GC3Denum target);
-
- bool getActiveAttrib(Platform3DObject program, GC3Duint index, ActiveInfo&);
- bool getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo&);
- void getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders);
- GC3Dint getAttribLocation(Platform3DObject, const String& name);
- void getBooleanv(GC3Denum paramName, GC3Dboolean* value);
- void getBufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value);
- GraphicsContext3D::Attributes getContextAttributes();
- GC3Denum getError();
- void getFloatv(GC3Denum paramName, GC3Dfloat* value);
- void getFramebufferAttachmentParameteriv(GC3Denum target, GC3Denum attachment, GC3Denum paramName, GC3Dint* value);
- void getIntegerv(GC3Denum paramName, GC3Dint* value);
- void getProgramiv(Platform3DObject program, GC3Denum paramName, GC3Dint* value);
- String getProgramInfoLog(Platform3DObject);
- void getRenderbufferParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value);
- void getShaderiv(Platform3DObject, GC3Denum paramName, GC3Dint* value);
- String getShaderInfoLog(Platform3DObject);
-
- String getShaderSource(Platform3DObject);
- String getString(GC3Denum name);
- void getTexParameterfv(GC3Denum target, GC3Denum paramName, GC3Dfloat* value);
- void getTexParameteriv(GC3Denum target, GC3Denum paramName, GC3Dint* value);
- void getUniformfv(Platform3DObject program, GC3Dint location, GC3Dfloat* value);
- void getUniformiv(Platform3DObject program, GC3Dint location, GC3Dint* value);
- GC3Dint getUniformLocation(Platform3DObject, const String& name);
- void getVertexAttribfv(GC3Duint index, GC3Denum paramName, GC3Dfloat* value);
- void getVertexAttribiv(GC3Duint index, GC3Denum paramName, GC3Dint* value);
- GC3Dsizeiptr getVertexAttribOffset(GC3Duint index, GC3Denum paramName);
-
- void hint(GC3Denum target, GC3Denum mode);
- GC3Dboolean isBuffer(Platform3DObject);
- GC3Dboolean isEnabled(GC3Denum cap);
- GC3Dboolean isFramebuffer(Platform3DObject);
- GC3Dboolean isProgram(Platform3DObject);
- GC3Dboolean isRenderbuffer(Platform3DObject);
- GC3Dboolean isShader(Platform3DObject);
- GC3Dboolean isTexture(Platform3DObject);
- void lineWidth(GC3Dfloat);
- void linkProgram(Platform3DObject);
- void pixelStorei(GC3Denum paramName, GC3Dint param);
- void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
-
- void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data);
-
- void renderbufferStorage(GC3Denum target, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height);
- void sampleCoverage(GC3Dclampf value, GC3Dboolean invert);
- void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void shaderSource(Platform3DObject, const String&);
- void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilMask(GC3Duint mask);
- void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
- void stencilOp(GC3Denum fail, GC3Denum zFail, GC3Denum zPass);
- void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zFail, GC3Denum zPass);
-
- bool texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
- void texParameterf(GC3Denum target, GC3Denum paramName, GC3Dfloat param);
- void texParameteri(GC3Denum target, GC3Denum paramName, GC3Dint param);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xOffset, GC3Dint yOffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels);
-
- void uniform1f(GC3Dint location, GC3Dfloat x);
- void uniform1fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
- void uniform1i(GC3Dint location, GC3Dint x);
- void uniform1iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
- void uniform2f(GC3Dint location, GC3Dfloat x, float y);
- void uniform2fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
- void uniform2i(GC3Dint location, GC3Dint x, GC3Dint y);
- void uniform2iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
- void uniform3f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void uniform3fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
- void uniform3i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z);
- void uniform3iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
- void uniform4f(GC3Dint location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void uniform4fv(GC3Dint location, GC3Dsizei, GC3Dfloat* v);
- void uniform4i(GC3Dint location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
- void uniform4iv(GC3Dint location, GC3Dsizei, GC3Dint* v);
- void uniformMatrix2fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
- void uniformMatrix3fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
- void uniformMatrix4fv(GC3Dint location, GC3Dsizei, GC3Dboolean transpose, GC3Dfloat* value);
-
- void useProgram(Platform3DObject);
- void validateProgram(Platform3DObject);
-
- void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
- void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values);
- void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
- void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values);
- void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values);
- void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values);
- void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, GC3Dintptr offset);
-
- void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- Platform3DObject createBuffer();
- Platform3DObject createFramebuffer();
- Platform3DObject createProgram();
- Platform3DObject createRenderbuffer();
- Platform3DObject createShader(GC3Denum);
- Platform3DObject createTexture();
-
- void deleteBuffer(Platform3DObject);
- void deleteFramebuffer(Platform3DObject);
- void deleteProgram(Platform3DObject);
- void deleteRenderbuffer(Platform3DObject);
- void deleteShader(Platform3DObject);
- void deleteTexture(Platform3DObject);
-
- void synthesizeGLError(GC3Denum error);
-
- Extensions3D* getExtensions();
-
-private:
- GraphicsContext3DPrivate();
-
- bool initialize(GraphicsContext3D::Attributes attrs, HostWindow*, bool renderDirectlyToHostWindow);
-
bool createSurface(PageClientEfl*, bool renderDirectlyToEvasGLObject);
+ void setCurrentGLContext(void*, void*);
GraphicsContext3D::Attributes m_attributes;
-
- Platform3DObject m_boundFBO;
- Platform3DObject m_boundTexture;
- Platform3DObject m_boundArrayBuffer;
+ GraphicsContext3D* m_context;
+ HostWindow* m_hostWindow;
ListHashSet<GC3Denum> m_syntheticErrors;
+ OwnPtr<Ecore_Evas> m_ecoreEvas;
Evas_GL* m_evasGL;
- Evas_GL_Context* m_context;
- Evas_GL_Surface* m_surface;
+ Evas_GL_Context* m_evasGLContext;
+ Evas_GL_Surface* m_evasGLSurface;
+ void* m_glContext;
+ void* m_glSurface;
Evas_GL_API* m_api;
+ GraphicsContext3D::RenderStyle m_renderStyle;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.cpp b/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.cpp
deleted file mode 100644
index a566bd064..000000000
--- a/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright (C) 2009-2011 Samsung Electronics
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public License
-along with this library; see the file COPYING.LIB. If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-
-#if USE(ACCELERATED_COMPOSITING)
-
-#include "GraphicsLayerEfl.h"
-
-#include "NotImplemented.h"
-
-namespace WebCore {
-
-PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
-{
- return adoptPtr(new GraphicsLayerEfl(client));
-}
-
-GraphicsLayerEfl::GraphicsLayerEfl(GraphicsLayerClient* client)
- : GraphicsLayer(client)
-{
-}
-
-GraphicsLayerEfl::~GraphicsLayerEfl()
-{
- willBeDestroyed();
-}
-
-void GraphicsLayerEfl::setNeedsDisplay()
-{
- notImplemented();
-}
-
-void GraphicsLayerEfl::setNeedsDisplayInRect(const FloatRect&)
-{
- notImplemented();
-}
-
-} // namespace WebCore
-
-#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp
new file mode 100644
index 000000000..b9389b483
--- /dev/null
+++ b/Source/WebCore/platform/graphics/egl/GLContextEGL.cpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2012 Igalia, S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "GLContextEGL.h"
+
+#if USE(EGL)
+
+#include "GraphicsContext3D.h"
+#include <wtf/OwnPtr.h>
+
+#if USE(OPENGL_ES_2)
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#else
+#include "OpenGLShims.h"
+#endif
+
+namespace WebCore {
+
+static EGLDisplay gSharedEGLDisplay = EGL_NO_DISPLAY;
+
+#if USE(OPENGL_ES_2)
+static const EGLenum gGLAPI = EGL_OPENGL_ES_API;
+#else
+static const EGLenum gGLAPI = EGL_OPENGL_API;
+#endif
+
+static EGLDisplay sharedEGLDisplay()
+{
+ static bool initialized = false;
+ if (!initialized) {
+ initialized = true;
+#if PLATFORM(X11)
+ gSharedEGLDisplay = eglGetDisplay(GLContext::sharedX11Display());
+#else
+ gSharedEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+#endif
+ if (gSharedEGLDisplay != EGL_NO_DISPLAY && (!eglInitialize(gSharedEGLDisplay, 0, 0) || !eglBindAPI(gGLAPI)))
+ gSharedEGLDisplay = EGL_NO_DISPLAY;
+ }
+ return gSharedEGLDisplay;
+}
+
+static const EGLint gContextAttributes[] = {
+#if USE(OPENGL_ES_2)
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+};
+
+static bool getEGLConfig(EGLConfig* config, GLContextEGL::EGLSurfaceType surfaceType)
+{
+ EGLint attributeList[] = {
+#if USE(OPENGL_ES_2)
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#else
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+#endif
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_STENCIL_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_NONE,
+ EGL_NONE
+ };
+
+ switch (surfaceType) {
+ case GLContextEGL::PbufferSurface:
+ attributeList[13] = EGL_PBUFFER_BIT;
+ break;
+ case GLContextEGL::PixmapSurface:
+ attributeList[13] = EGL_PIXMAP_BIT;
+ break;
+ case GLContextEGL::WindowSurface:
+ attributeList[13] = EGL_WINDOW_BIT;
+ break;
+ }
+
+ EGLint numberConfigsReturned;
+ return eglChooseConfig(sharedEGLDisplay(), attributeList, config, 1, &numberConfigsReturned) && numberConfigsReturned;
+}
+
+PassOwnPtr<GLContextEGL> GLContextEGL::createWindowContext(EGLNativeWindowType window, GLContext* sharingContext)
+{
+ EGLContext eglSharingContext = sharingContext ? static_cast<GLContextEGL*>(sharingContext)->m_context : 0;
+
+ EGLDisplay display = sharedEGLDisplay();
+ if (display == EGL_NO_DISPLAY)
+ return nullptr;
+
+ EGLConfig config;
+ if (!getEGLConfig(&config, WindowSurface))
+ return nullptr;
+
+ EGLContext context = eglCreateContext(display, config, eglSharingContext, gContextAttributes);
+ if (context == EGL_NO_CONTEXT)
+ return nullptr;
+
+ EGLSurface surface = eglCreateWindowSurface(display, config, window, 0);
+ if (surface == EGL_NO_SURFACE)
+ return nullptr;
+
+ return adoptPtr(new GLContextEGL(context, surface, WindowSurface));
+}
+
+PassOwnPtr<GLContextEGL> GLContextEGL::createPbufferContext(EGLContext sharingContext)
+{
+ EGLDisplay display = sharedEGLDisplay();
+ if (display == EGL_NO_DISPLAY)
+ return nullptr;
+
+ EGLConfig config;
+ if (!getEGLConfig(&config, PbufferSurface))
+ return nullptr;
+
+ EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
+ if (context == EGL_NO_CONTEXT)
+ return nullptr;
+
+ static const int pbufferAttributes[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
+ EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttributes);
+ if (surface == EGL_NO_SURFACE) {
+ eglDestroyContext(display, context);
+ return nullptr;
+ }
+
+ return adoptPtr(new GLContextEGL(context, surface, PbufferSurface));
+}
+
+PassOwnPtr<GLContextEGL> GLContextEGL::createPixmapContext(EGLContext sharingContext)
+{
+#if PLATFORM(X11)
+ EGLDisplay display = sharedEGLDisplay();
+ if (display == EGL_NO_DISPLAY)
+ return nullptr;
+
+ EGLConfig config;
+ if (!getEGLConfig(&config, PixmapSurface))
+ return nullptr;
+
+ EGLContext context = eglCreateContext(display, config, sharingContext, gContextAttributes);
+ if (context == EGL_NO_CONTEXT)
+ return nullptr;
+
+ EGLint depth;
+ if (!eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depth))
+ return nullptr;
+
+ Pixmap pixmap = XCreatePixmap(sharedX11Display(), DefaultRootWindow(sharedX11Display()), 1, 1, depth);
+ if (!pixmap)
+ return nullptr;
+
+ EGLSurface surface = eglCreatePixmapSurface(display, config, pixmap, 0);
+#else
+ EGLSurface surface = EGL_NO_SURFACE;
+#endif
+ if (surface == EGL_NO_SURFACE)
+ return nullptr;
+
+ return adoptPtr(new GLContextEGL(context, surface, PixmapSurface));
+}
+
+PassOwnPtr<GLContextEGL> GLContextEGL::createContext(EGLNativeWindowType window, GLContext* sharingContext)
+{
+ if (!sharedEGLDisplay())
+ return nullptr;
+
+ static bool initialized = false;
+ static bool success = true;
+ if (!initialized) {
+#if !USE(OPENGL_ES_2)
+ success = initializeOpenGLShims();
+#endif
+ initialized = true;
+ }
+ if (!success)
+ return nullptr;
+
+ EGLContext eglSharingContext = sharingContext ? static_cast<GLContextEGL*>(sharingContext)->m_context : 0;
+ OwnPtr<GLContextEGL> context = window ? createWindowContext(window, sharingContext) : nullptr;
+ if (!context)
+ context = createPixmapContext(eglSharingContext);
+
+ if (!context)
+ context = createPbufferContext(eglSharingContext);
+
+ return context.release();
+}
+
+GLContextEGL::GLContextEGL(EGLContext context, EGLSurface surface, EGLSurfaceType type)
+ : m_context(context)
+ , m_surface(surface)
+ , m_type(type)
+{
+}
+
+GLContextEGL::~GLContextEGL()
+{
+ EGLDisplay display = sharedEGLDisplay();
+ if (m_context) {
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(display, m_context);
+ }
+
+ if (m_surface)
+ eglDestroySurface(display, m_surface);
+}
+
+bool GLContextEGL::canRenderToDefaultFramebuffer()
+{
+ return m_type == WindowSurface;
+}
+
+IntSize GLContextEGL::defaultFrameBufferSize()
+{
+ if (!canRenderToDefaultFramebuffer())
+ return IntSize();
+
+ EGLint width, height;
+ if (!eglQuerySurface(sharedEGLDisplay(), m_surface, EGL_WIDTH, &width)
+ || !eglQuerySurface(sharedEGLDisplay(), m_surface, EGL_HEIGHT, &height))
+ return IntSize();
+
+ return IntSize(width, height);
+}
+
+bool GLContextEGL::makeContextCurrent()
+{
+ ASSERT(m_context && m_surface);
+
+ GLContext::makeContextCurrent();
+ if (eglGetCurrentContext() == m_context)
+ return true;
+
+ return eglMakeCurrent(sharedEGLDisplay(), m_surface, m_surface, m_context);
+}
+
+void GLContextEGL::swapBuffers()
+{
+ ASSERT(m_surface);
+ eglSwapBuffers(sharedEGLDisplay(), m_surface);
+}
+
+void GLContextEGL::waitNative()
+{
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+}
+
+#if ENABLE(WEBGL)
+PlatformGraphicsContext3D GLContextEGL::platformContext()
+{
+ return m_context;
+}
+#endif
+
+} // namespace WebCore
+
+#endif // USE(EGL)
diff --git a/Source/WebCore/platform/graphics/egl/GLContextEGL.h b/Source/WebCore/platform/graphics/egl/GLContextEGL.h
new file mode 100644
index 000000000..c5d4bf756
--- /dev/null
+++ b/Source/WebCore/platform/graphics/egl/GLContextEGL.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GLContextEGL_h
+#define GLContextEGL_h
+
+#if USE(EGL)
+
+#include "GLContext.h"
+
+#include <EGL/egl.h>
+
+namespace WebCore {
+
+class GLContextEGL : public GLContext {
+ WTF_MAKE_NONCOPYABLE(GLContextEGL);
+public:
+ enum EGLSurfaceType { PbufferSurface, WindowSurface, PixmapSurface };
+ static PassOwnPtr<GLContextEGL> createContext(EGLNativeWindowType, GLContext* sharingContext = 0);
+ static PassOwnPtr<GLContextEGL> createWindowContext(EGLNativeWindowType, GLContext* sharingContext);
+
+ virtual ~GLContextEGL();
+ virtual bool makeContextCurrent();
+ virtual void swapBuffers();
+ virtual void waitNative();
+ virtual bool canRenderToDefaultFramebuffer();
+ virtual IntSize defaultFrameBufferSize();
+
+
+#if ENABLE(WEBGL)
+ virtual PlatformGraphicsContext3D platformContext();
+#endif
+
+private:
+ static PassOwnPtr<GLContextEGL> createPbufferContext(EGLContext sharingContext);
+ static PassOwnPtr<GLContextEGL> createPixmapContext(EGLContext sharingContext);
+
+ static void addActiveContext(GLContextEGL*);
+ static void cleanupSharedEGLDisplay(void);
+
+ GLContextEGL(EGLContext, EGLSurface, EGLSurfaceType);
+
+ EGLContext m_context;
+ EGLSurface m_surface;
+ EGLSurfaceType m_type;
+};
+
+} // namespace WebCore
+
+#endif // USE(EGL)
+
+#endif // GLContextEGL_h
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h b/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h
new file mode 100644
index 000000000..6080c38f6
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterConstants.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “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 HOLDER 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 CustomFilterConstants_h
+#define CustomFilterConstants_h
+
+namespace WebCore {
+
+enum CustomFilterMeshConstants {
+ // Vertex attribute sizes
+ PositionAttribSize = 4,
+ TexAttribSize = 2,
+ MeshAttribSize = 2,
+ TriangleAttribSize = 3,
+ // Vertex attribute offsets
+ PositionAttribOffset = 0,
+ TexAttribOffset = PositionAttribOffset + PositionAttribSize * sizeof(float),
+ MeshAttribOffset = TexAttribOffset + TexAttribSize * sizeof(float),
+ TriangleAttribOffset = MeshAttribOffset + MeshAttribSize * sizeof(float)
+};
+
+} // namespace WebCore
+
+#endif // CustomFilterConstants_h
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp
index da9782af8..02a96b864 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp
@@ -44,7 +44,7 @@ CustomFilterGlobalContext::CustomFilterGlobalContext()
CustomFilterGlobalContext::~CustomFilterGlobalContext()
{
for (CustomFilterValidatedProgramsMap::iterator iter = m_programs.begin(); iter != m_programs.end(); ++iter)
- iter->second->detachFromGlobalContext();
+ iter->value->detachFromGlobalContext();
}
ANGLEWebKitBridge* CustomFilterGlobalContext::webglShaderValidator()
@@ -91,7 +91,7 @@ PassRefPtr<CustomFilterValidatedProgram> CustomFilterGlobalContext::getValidated
{
CustomFilterValidatedProgramsMap::iterator iter = m_programs.find(programInfo);
if (iter != m_programs.end())
- return iter->second;
+ return iter->value;
RefPtr<CustomFilterValidatedProgram> validatedProgram = CustomFilterValidatedProgram::create(this, programInfo);
m_programs.set(programInfo, validatedProgram.get());
@@ -107,7 +107,7 @@ void CustomFilterGlobalContext::removeValidatedProgram(const CustomFilterValidat
#ifndef NDEBUG
// Check that there's no way we could have the same program under a different key.
for (iter = m_programs.begin(); iter != m_programs.end(); ++iter)
- ASSERT(iter->second != program);
+ ASSERT(iter->value != program);
#endif
}
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
index 09f75621b..b3a184702 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterMeshGenerator.h
@@ -32,6 +32,7 @@
#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+#include "CustomFilterConstants.h"
#include "CustomFilterOperation.h"
#include "FloatRect.h"
@@ -63,13 +64,8 @@ public:
unsigned floatsPerVertex() const
{
- static const unsigned AttachedMeshVertexSize = 4 + // vec4 a_position
- 2 + // vec2 a_texCoord
- 2; // vec2 a_meshCoord
-
- static const unsigned DetachedMeshVertexSize = AttachedMeshVertexSize +
- 3; // vec3 a_triangleCoord
-
+ static const unsigned AttachedMeshVertexSize = PositionAttribSize + TexAttribSize + MeshAttribSize;
+ static const unsigned DetachedMeshVertexSize = AttachedMeshVertexSize + TriangleAttribSize;
return m_meshType == CustomFilterOperation::ATTACHED ? AttachedMeshVertexSize : DetachedMeshVertexSize;
}
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
index d1cf6134f..c9990d98d 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp
@@ -38,8 +38,9 @@
namespace WebCore {
-CustomFilterProgram::CustomFilterProgram(CustomFilterProgramMixSettings mixSettings)
- : m_mixSettings(mixSettings)
+CustomFilterProgram::CustomFilterProgram(CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings)
+ : m_programType(programType)
+ , m_mixSettings(mixSettings)
{
// Keep the constructor protected to prevent creating this object directly.
}
@@ -75,13 +76,13 @@ void CustomFilterProgram::removeClient(CustomFilterProgramClient* client)
void CustomFilterProgram::notifyClients()
{
for (CustomFilterProgramClientList::iterator iter = m_clients.begin(), end = m_clients.end(); iter != end; ++iter)
- iter->first->notifyCustomFilterProgramLoaded(this);
+ iter->key->notifyCustomFilterProgramLoaded(this);
}
CustomFilterProgramInfo CustomFilterProgram::programInfo() const
{
ASSERT(isLoaded());
- return CustomFilterProgramInfo(vertexShaderString(), fragmentShaderString(), m_mixSettings);
+ return CustomFilterProgramInfo(vertexShaderString(), fragmentShaderString(), m_programType, m_mixSettings);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
index ef19dfb83..0492d476d 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h
@@ -58,6 +58,7 @@ public:
void removeClient(CustomFilterProgramClient*);
CustomFilterProgramInfo programInfo() const;
+ CustomFilterProgramType programType() const { return m_programType; }
// StyleCustomFilterProgram has the only implementation for the following method. That means, it casts to StyleCustomFilterProgram
// withouth checking the type. If you add another implementation, also add a mechanism to check for the correct type.
@@ -75,11 +76,12 @@ protected:
virtual void didRemoveLastClient() = 0;
// Keep the constructor protected to prevent creating this object directly.
- CustomFilterProgram(CustomFilterProgramMixSettings);
+ CustomFilterProgram(CustomFilterProgramType, const CustomFilterProgramMixSettings&);
private:
typedef HashCountedSet<CustomFilterProgramClient*> CustomFilterProgramClientList;
CustomFilterProgramClientList m_clients;
+ CustomFilterProgramType m_programType;
CustomFilterProgramMixSettings m_mixSettings;
};
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
index 1bf6a91f0..bc1494faf 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp
@@ -64,9 +64,10 @@ bool CustomFilterProgramInfo::isHashTableDeletedValue() const
&& m_fragmentShaderString.isHashTableDeletedValue();
}
-CustomFilterProgramInfo::CustomFilterProgramInfo(const String& vertexShader, const String& fragmentShader, const CustomFilterProgramMixSettings& mixSettings)
+CustomFilterProgramInfo::CustomFilterProgramInfo(const String& vertexShader, const String& fragmentShader, CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings)
: m_vertexShaderString(vertexShader)
, m_fragmentShaderString(fragmentShader)
+ , m_programType(programType)
, m_mixSettings(mixSettings)
{
// At least one of the shaders needs to be non-null.
@@ -80,9 +81,9 @@ unsigned CustomFilterProgramInfo::hash() const
uintptr_t hashCodes[5] = {
hashPossiblyNullString(m_vertexShaderString),
hashPossiblyNullString(m_fragmentShaderString),
- m_mixSettings.enabled,
- m_mixSettings.enabled ? m_mixSettings.blendMode : 0,
- m_mixSettings.enabled ? m_mixSettings.compositeOperator : 0
+ m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE,
+ m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? m_mixSettings.blendMode : 0,
+ m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? m_mixSettings.compositeOperator : 0
};
return StringHasher::hashMemory<sizeof(hashCodes)>(&hashCodes);
}
@@ -91,9 +92,16 @@ bool CustomFilterProgramInfo::operator==(const CustomFilterProgramInfo& o) const
{
ASSERT(!isHashTableDeletedValue());
ASSERT(!o.isHashTableDeletedValue());
+
+ if (m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE)
+ return m_vertexShaderString == o.m_vertexShaderString
+ && m_fragmentShaderString == o.m_fragmentShaderString
+ && m_programType == o.m_programType
+ && m_mixSettings == o.m_mixSettings;
+
return m_vertexShaderString == o.m_vertexShaderString
&& m_fragmentShaderString == o.m_fragmentShaderString
- && m_mixSettings == o.m_mixSettings;
+ && m_programType == o.m_programType;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
index 52fe77157..3b544c5ad 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h
@@ -45,19 +45,16 @@ enum CustomFilterProgramType {
struct CustomFilterProgramMixSettings {
CustomFilterProgramMixSettings()
- : enabled(false)
- , blendMode(BlendModeNormal)
+ : blendMode(BlendModeNormal)
, compositeOperator(CompositeSourceOver)
{
}
bool operator==(const CustomFilterProgramMixSettings& o) const
{
- return (!enabled && !o.enabled)
- || (blendMode == o.blendMode && compositeOperator == o.compositeOperator);
+ return blendMode == o.blendMode && compositeOperator == o.compositeOperator;
}
- bool enabled;
BlendMode blendMode;
CompositeOperator compositeOperator;
};
@@ -67,7 +64,7 @@ struct CustomFilterProgramMixSettings {
// Null strings are placeholders for the default shader.
class CustomFilterProgramInfo {
public:
- CustomFilterProgramInfo(const String&, const String&, const CustomFilterProgramMixSettings&);
+ CustomFilterProgramInfo(const String&, const String&, CustomFilterProgramType, const CustomFilterProgramMixSettings&);
CustomFilterProgramInfo();
bool isEmptyValue() const;
@@ -80,13 +77,12 @@ public:
const String& vertexShaderString() const { return m_vertexShaderString; }
const String& fragmentShaderString() const { return m_fragmentShaderString; }
- // FIXME: We should add CustomFilterProgramType to CustomFilterProgramInfo and remove mixSettings.enabled.
- // https://bugs.webkit.org/show_bug.cgi?id=96448
- CustomFilterProgramType programType() const { return m_mixSettings.enabled ? PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE : PROGRAM_TYPE_NO_ELEMENT_TEXTURE; }
+ CustomFilterProgramType programType() const { return m_programType; }
const CustomFilterProgramMixSettings& mixSettings() const { return m_mixSettings; }
private:
String m_vertexShaderString;
String m_fragmentShaderString;
+ CustomFilterProgramType m_programType;
CustomFilterProgramMixSettings m_mixSettings;
};
diff --git a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
index 4211e82b7..85ddda5a2 100644
--- a/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
+++ b/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp
@@ -83,10 +83,12 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
originalFragmentShader = defaultFragmentShaderString();
// Shaders referenced from the CSS mix function use a different validator than regular WebGL shaders. See CustomFilterGlobalContext.h for more details.
- ANGLEWebKitBridge* validator = programInfo.mixSettings().enabled ? m_globalContext->mixShaderValidator() : m_globalContext->webglShaderValidator();
+ bool blendsElementTexture = (programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
+ ANGLEWebKitBridge* validator = blendsElementTexture ? m_globalContext->mixShaderValidator() : m_globalContext->webglShaderValidator();
String vertexShaderLog, fragmentShaderLog;
- bool vertexShaderValid = validator->validateShaderSource(originalVertexShader.utf8().data(), SHADER_TYPE_VERTEX, m_validatedVertexShader, vertexShaderLog, SH_ATTRIBUTES_UNIFORMS);
- bool fragmentShaderValid = validator->validateShaderSource(originalFragmentShader.utf8().data(), SHADER_TYPE_FRAGMENT, m_validatedFragmentShader, fragmentShaderLog, SH_ATTRIBUTES_UNIFORMS);
+ Vector<ANGLEShaderSymbol> symbols;
+ bool vertexShaderValid = validator->compileShaderSource(originalVertexShader.utf8().data(), SHADER_TYPE_VERTEX, m_validatedVertexShader, vertexShaderLog, symbols);
+ bool fragmentShaderValid = validator->compileShaderSource(originalFragmentShader.utf8().data(), SHADER_TYPE_FRAGMENT, m_validatedFragmentShader, fragmentShaderLog, symbols);
if (!vertexShaderValid || !fragmentShaderValid) {
// FIXME: Report the validation errors.
// https://bugs.webkit.org/show_bug.cgi?id=74416
@@ -94,12 +96,7 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
}
// Validate the author's samplers.
- Vector<ANGLEShaderSymbol> uniforms;
- if (!validator->getUniforms(SH_VERTEX_SHADER, uniforms))
- return;
- if (!validator->getUniforms(SH_FRAGMENT_SHADER, uniforms))
- return;
- for (Vector<ANGLEShaderSymbol>::iterator it = uniforms.begin(); it != uniforms.end(); ++it) {
+ for (Vector<ANGLEShaderSymbol>::iterator it = symbols.begin(); it != symbols.end(); ++it) {
if (it->isSampler()) {
// FIXME: For now, we restrict shaders with any sampler defined.
// When we implement texture parameters, we will allow shaders whose samplers are bound to valid textures.
@@ -111,7 +108,7 @@ CustomFilterValidatedProgram::CustomFilterValidatedProgram(CustomFilterGlobalCon
}
// We need to add texture access, blending, and compositing code to shaders that are referenced from the CSS mix function.
- if (programInfo.mixSettings().enabled) {
+ if (blendsElementTexture) {
rewriteMixVertexShader();
rewriteMixFragmentShader();
}
@@ -129,7 +126,7 @@ PassRefPtr<CustomFilterCompiledProgram> CustomFilterValidatedProgram::compiledPr
void CustomFilterValidatedProgram::rewriteMixVertexShader()
{
- ASSERT(m_programInfo.mixSettings().enabled);
+ ASSERT(m_programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
// During validation, ANGLE renamed the author's "main" function to "css_main".
// We write our own "main" function and call "css_main" from it.
@@ -148,7 +145,7 @@ void CustomFilterValidatedProgram::rewriteMixVertexShader()
void CustomFilterValidatedProgram::rewriteMixFragmentShader()
{
- ASSERT(m_programInfo.mixSettings().enabled);
+ ASSERT(m_programInfo.programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
StringBuilder builder;
// ANGLE considered these symbols as built-ins during validation under the SH_CSS_SHADERS_SPEC flag.
diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
index a4a6f9ed3..fad92c95a 100644
--- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
@@ -243,6 +243,12 @@ ALWAYS_INLINE void setDestinationPixels(Uint8ClampedArray* image, int& pixel, fl
image->set(pixel++, maxAlpha);
}
+#if defined(_MSC_VER) && (_MSC_VER >= 1700)
+// Incorrectly diagnosing overwrite of stack in |totals| due to |preserveAlphaValues|.
+#pragma warning(push)
+#pragma warning(disable: 4789)
+#endif
+
// Only for region C
template<bool preserveAlphaValues>
ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
@@ -381,6 +387,10 @@ void FEConvolveMatrix::fastSetOuterPixels(PaintingData& paintingData, int x1, in
}
}
+#if defined(_MSC_VER) && (_MSC_VER >= 1700)
+#pragma warning(pop) // Disable of 4789
+#endif
+
ALWAYS_INLINE void FEConvolveMatrix::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom, int yStart, int yEnd)
{
// Must be implemented here, since it refers another ALWAYS_INLINE
@@ -444,9 +454,13 @@ void FEConvolveMatrix::platformApplySoftware()
if (optimalThreadNumber > 1) {
WTF::ParallelJobs<InteriorPixelParameters> parallelJobs(&WebCore::FEConvolveMatrix::setInteriorPixelsWorker, optimalThreadNumber);
const int numOfThreads = parallelJobs.numberOfJobs();
+
+ // Split the job into "heightPerThread" jobs but there a few jobs that need to be slightly larger since
+ // heightPerThread * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
const int heightPerThread = clipBottom / numOfThreads;
- int startY = 0;
+ const int jobsWithExtra = clipBottom % numOfThreads;
+ int startY = 0;
for (int job = 0; job < numOfThreads; ++job) {
InteriorPixelParameters& param = parallelJobs.parameter(job);
param.filter = this;
@@ -454,11 +468,8 @@ void FEConvolveMatrix::platformApplySoftware()
param.clipRight = clipRight;
param.clipBottom = clipBottom;
param.yStart = startY;
- if (job < numOfThreads - 1) {
- startY += heightPerThread;
- param.yEnd = startY - 1;
- } else
- param.yEnd = clipBottom;
+ startY += job < jobsWithExtra ? heightPerThread + 1 : heightPerThread;
+ param.yEnd = startY;
}
parallelJobs.execute();
diff --git a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp b/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
index fb5760f0b..707edb866 100644
--- a/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
+++ b/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp
@@ -35,6 +35,7 @@
#include "CustomFilterArrayParameter.h"
#include "CustomFilterCompiledProgram.h"
+#include "CustomFilterConstants.h"
#include "CustomFilterGlobalContext.h"
#include "CustomFilterMesh.h"
#include "CustomFilterNumberParameter.h"
@@ -224,7 +225,7 @@ bool FECustomFilter::programNeedsInputTexture() const
bool FECustomFilter::applyShader()
{
- Uint8ClampedArray* dstPixelArray = createUnmultipliedImageResult();
+ Uint8ClampedArray* dstPixelArray = m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE ? createPremultipliedImageResult() : createUnmultipliedImageResult();
if (!dstPixelArray)
return false;
@@ -299,7 +300,8 @@ bool FECustomFilter::createMultisampleBuffer()
m_triedMultisampleBuffer = true;
Extensions3D* extensions = m_context->getExtensions();
- if (!extensions
+ if (!extensions
+ || !extensions->maySupportMultisampling()
|| !extensions->supports("GL_ANGLE_framebuffer_multisample")
|| !extensions->supports("GL_ANGLE_framebuffer_blit")
|| !extensions->supports("GL_OES_rgb8_rgba8"))
@@ -569,18 +571,6 @@ void FECustomFilter::bindProgramAndBuffers(Platform3DObject inputTexture)
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_mesh->verticesBufferObject());
m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());
- // FIXME: Ideally, these should be public members of CustomFilterMesh.
- // https://bugs.webkit.org/show_bug.cgi?id=94755
- static const unsigned PositionAttribSize = 4;
- static const unsigned TexAttribSize = 2;
- static const unsigned MeshAttribSize = 2;
- static const unsigned TriangleAttribSize = 3;
-
- static const unsigned PositionAttribOffset = 0;
- static const unsigned TexAttribOffset = PositionAttribOffset + PositionAttribSize * sizeof(float);
- static const unsigned MeshAttribOffset = TexAttribOffset + TexAttribSize * sizeof(float);
- static const unsigned TriangleAttribOffset = MeshAttribOffset + MeshAttribSize * sizeof(float);
-
bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
// FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
diff --git a/Source/WebCore/platform/graphics/filters/FECustomFilter.h b/Source/WebCore/platform/graphics/filters/FECustomFilter.h
index e4a2e41d3..09da5f1c7 100644
--- a/Source/WebCore/platform/graphics/filters/FECustomFilter.h
+++ b/Source/WebCore/platform/graphics/filters/FECustomFilter.h
@@ -50,7 +50,6 @@ class CustomFilterCompiledProgram;
class CustomFilterGlobalContext;
class CustomFilterMesh;
class CustomFilterNumberParameter;
-class CustomFilterProgram;
class CustomFilterTransformParameter;
class CustomFilterValidatedProgram;
class DrawingBuffer;
@@ -128,7 +127,6 @@ private:
Platform3DObject m_multisampleRenderBuffer;
Platform3DObject m_multisampleDepthBuffer;
- RefPtr<CustomFilterProgram> m_program;
CustomFilterParameterList m_parameters;
unsigned m_meshRows;
diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
index 43731f70d..cb9562f69 100644
--- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -171,29 +171,25 @@ inline void FEGaussianBlur::platformApply(Uint8ClampedArray* srcPixelArray, Uint
int jobs = parallelJobs.numberOfJobs();
if (jobs > 1) {
- int blockHeight = paintSize.height() / jobs;
- --jobs;
- for (int job = jobs; job >= 0; --job) {
+ // Split the job into "blockHeight"-sized jobs but there a few jobs that need to be slightly larger since
+ // blockHeight * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+ const int blockHeight = paintSize.height() / jobs;
+ const int jobsWithExtra = paintSize.height() % jobs;
+
+ int currentY = 0;
+ for (int job = 0; job < jobs; job++) {
PlatformApplyParameters& params = parallelJobs.parameter(job);
params.filter = this;
- int startY;
- int endY;
+ int startY = !job ? 0 : currentY - extraHeight;
+ currentY += job < jobsWithExtra ? blockHeight + 1 : blockHeight;
+ int endY = job == jobs - 1 ? currentY : currentY + extraHeight;
+
+ int blockSize = (endY - startY) * scanline;
if (!job) {
- startY = 0;
- endY = blockHeight + extraHeight;
params.srcPixelArray = srcPixelArray;
params.dstPixelArray = tmpPixelArray;
} else {
- if (job == jobs) {
- startY = job * blockHeight - extraHeight;
- endY = paintSize.height();
- } else {
- startY = job * blockHeight - extraHeight;
- endY = (job + 1) * blockHeight + extraHeight;
- }
-
- int blockSize = (endY - startY) * scanline;
params.srcPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
params.dstPixelArray = Uint8ClampedArray::createUninitialized(blockSize);
memcpy(params.srcPixelArray->data(), srcPixelArray->data() + startY * scanline, blockSize);
@@ -208,20 +204,19 @@ inline void FEGaussianBlur::platformApply(Uint8ClampedArray* srcPixelArray, Uint
parallelJobs.execute();
// Copy together the parts of the image.
- for (int job = jobs; job >= 1; --job) {
+ currentY = 0;
+ for (int job = 1; job < jobs; job++) {
PlatformApplyParameters& params = parallelJobs.parameter(job);
int sourceOffset;
int destinationOffset;
int size;
- if (job == jobs) {
- sourceOffset = extraHeight * scanline;
- destinationOffset = job * blockHeight * scanline;
- size = (paintSize.height() - job * blockHeight) * scanline;
- } else {
- sourceOffset = extraHeight * scanline;
- destinationOffset = job * blockHeight * scanline;
- size = blockHeight * scanline;
- }
+ int adjustedBlockHeight = job < jobsWithExtra ? blockHeight + 1 : blockHeight;
+
+ currentY += adjustedBlockHeight;
+ sourceOffset = extraHeight * scanline;
+ destinationOffset = currentY * scanline;
+ size = adjustedBlockHeight * scanline;
+
memcpy(srcPixelArray->data() + destinationOffset, params.srcPixelArray->data() + sourceOffset, size);
}
return;
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.cpp b/Source/WebCore/platform/graphics/filters/FELighting.cpp
index bcb3c165e..1a8180334 100644
--- a/Source/WebCore/platform/graphics/filters/FELighting.cpp
+++ b/Source/WebCore/platform/graphics/filters/FELighting.cpp
@@ -257,19 +257,20 @@ inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::Pa
// Fill the parameter array
int job = parallelJobs.numberOfJobs();
if (job > 1) {
+ // Split the job into "yStep"-sized jobs but there a few jobs that need to be slightly larger since
+ // yStep * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+ const int yStep = (data.heightDecreasedByOne - 1) / job;
+ const int jobsWithExtra = (data.heightDecreasedByOne - 1) % job;
+
int yStart = 1;
- int yStep = (data.heightDecreasedByOne - 1) / job;
for (--job; job >= 0; --job) {
PlatformApplyGenericParameters& params = parallelJobs.parameter(job);
params.filter = this;
params.data = data;
params.paintingData = paintingData;
params.yStart = yStart;
- if (job > 0) {
- params.yEnd = yStart + yStep;
- yStart += yStep;
- } else
- params.yEnd = data.heightDecreasedByOne;
+ yStart += job < jobsWithExtra ? yStep + 1 : yStep;
+ params.yEnd = yStart;
}
parallelJobs.execute();
return;
diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp
index 98d2a6a01..9e720f74a 100644
--- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp
+++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp
@@ -173,14 +173,17 @@ void FEMorphology::platformApply(PaintingData* paintingData)
ParallelJobs<PlatformApplyParameters> parallelJobs(&WebCore::FEMorphology::platformApplyWorker, optimalThreadNumber);
int numOfThreads = parallelJobs.numberOfJobs();
if (numOfThreads > 1) {
- const int deltaY = 1 + paintingData->height / numOfThreads;
+ // Split the job into "jobSize"-sized jobs but there a few jobs that need to be slightly larger since
+ // jobSize * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+ const int jobSize = paintingData->height / numOfThreads;
+ const int jobsWithExtra = paintingData->height % numOfThreads;
int currentY = 0;
for (int job = numOfThreads - 1; job >= 0; --job) {
PlatformApplyParameters& param = parallelJobs.parameter(job);
param.filter = this;
param.startY = currentY;
- currentY += deltaY;
- param.endY = job ? currentY : paintingData->height;
+ currentY += job < jobsWithExtra ? jobSize + 1 : jobSize;
+ param.endY = currentY;
param.paintingData = paintingData;
}
parallelJobs.execute();
diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
index 03df56b30..17688746f 100644
--- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
+++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
@@ -376,19 +376,20 @@ void FETurbulence::platformApplySoftware()
// Fill the parameter array
int i = parallelJobs.numberOfJobs();
if (i > 1) {
+ // Split the job into "stepY"-sized jobs but there a few jobs that need to be slightly larger since
+ // stepY * jobs < total size. These extras are handled by the remainder "jobsWithExtra".
+ const int stepY = absolutePaintRect().height() / i;
+ const int jobsWithExtra = absolutePaintRect().height() % i;
+
int startY = 0;
- int stepY = absolutePaintRect().height() / i;
for (; i > 0; --i) {
FillRegionParameters& params = parallelJobs.parameter(i-1);
params.filter = this;
params.pixelArray = pixelArray;
params.paintingData = &paintingData;
params.startY = startY;
- if (i != 1) {
- params.endY = startY + stepY;
- startY = startY + stepY;
- } else
- params.endY = absolutePaintRect().height();
+ startY += i < jobsWithExtra ? stepY + 1 : stepY;
+ params.endY = startY;
}
// Execute parallel jobs
diff --git a/Source/WebCore/platform/graphics/filters/arm/FECompositeArithmeticNEON.h b/Source/WebCore/platform/graphics/filters/arm/FECompositeArithmeticNEON.h
index 50f34b77a..2354dfc80 100644
--- a/Source/WebCore/platform/graphics/filters/arm/FECompositeArithmeticNEON.h
+++ b/Source/WebCore/platform/graphics/filters/arm/FECompositeArithmeticNEON.h
@@ -27,8 +27,6 @@
#ifndef FECompositeArithmeticNEON_h
#define FECompositeArithmeticNEON_h
-#include <wtf/Platform.h>
-
#if ENABLE(FILTERS) && HAVE(ARM_NEON_INTRINSICS)
#include "FEComposite.h"
diff --git a/Source/WebCore/platform/graphics/filters/arm/FEGaussianBlurNEON.h b/Source/WebCore/platform/graphics/filters/arm/FEGaussianBlurNEON.h
index 93b46cfd3..3779c2ec5 100644
--- a/Source/WebCore/platform/graphics/filters/arm/FEGaussianBlurNEON.h
+++ b/Source/WebCore/platform/graphics/filters/arm/FEGaussianBlurNEON.h
@@ -27,8 +27,6 @@
#ifndef FEGaussianBlurNEON_h
#define FEGaussianBlurNEON_h
-#include <wtf/Platform.h>
-
#if ENABLE(FILTERS) && HAVE(ARM_NEON_INTRINSICS)
#include "FEGaussianBlur.h"
@@ -37,13 +35,14 @@
namespace WebCore {
inline void boxBlurNEON(Uint8ClampedArray* srcPixelArray, Uint8ClampedArray* dstPixelArray,
- unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight)
+ unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight)
{
uint32_t* sourcePixel = reinterpret_cast<uint32_t*>(srcPixelArray->data());
uint32_t* destinationPixel = reinterpret_cast<uint32_t*>(dstPixelArray->data());
float32x4_t deltaX = vdupq_n_f32(1.0 / dx);
int pixelLine = strideLine / 4;
+ int pixelStride = stride / 4;
for (int y = 0; y < effectHeight; ++y) {
int line = y * pixelLine;
@@ -51,21 +50,21 @@ inline void boxBlurNEON(Uint8ClampedArray* srcPixelArray, Uint8ClampedArray* dst
// Fill the kernel
int maxKernelSize = std::min(dxRight, effectWidth);
for (int i = 0; i < maxKernelSize; ++i) {
- float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + line + i);
+ float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + line + i * pixelStride);
sum = vaddq_f32(sum, sourcePixelAsFloat);
}
// Blurring
for (int x = 0; x < effectWidth; ++x) {
- int pixelOffset = line + x;
+ int pixelOffset = line + x * pixelStride;
float32x4_t result = vmulq_f32(sum, deltaX);
- storeFloatAsRGBA8(result, destinationPixel+pixelOffset);
+ storeFloatAsRGBA8(result, destinationPixel + pixelOffset);
if (x >= dxLeft) {
- float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + pixelOffset - dxLeft);
+ float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + pixelOffset - dxLeft * pixelStride);
sum = vsubq_f32(sum, sourcePixelAsFloat);
}
if (x + dxRight < effectWidth) {
- float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + pixelOffset + dxRight);
+ float32x4_t sourcePixelAsFloat = loadRGBA8AsFloat(sourcePixel + pixelOffset + dxRight * pixelStride);
sum = vaddq_f32(sum, sourcePixelAsFloat);
}
}
diff --git a/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h
index 13c975c09..682922f50 100644
--- a/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h
+++ b/Source/WebCore/platform/graphics/filters/arm/FELightingNEON.h
@@ -27,8 +27,6 @@
#ifndef FELightingNeon_h
#define FELightingNeon_h
-#include <wtf/Platform.h>
-
#if CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC)
#include "FELighting.h"
diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
index 490517867..3e6bcfa9a 100644
--- a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
@@ -81,7 +81,7 @@ FcPattern* findBestFontGivenFallbacks(const FontPlatformData& fontData, FcPatter
return FcFontSetMatch(0, sets, 1, pattern, &fontConfigResult);
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
RefPtr<FcPattern> pattern = adoptRef(createFontConfigPatternForCharacters(characters, length));
const FontPlatformData& fontData = font.primaryFont()->platformData();
@@ -100,12 +100,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
return getCachedFontData(&alternateFontData, DoNotRetain);
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font&)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font&)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
// We want to return a fallback font here, otherwise the logic preventing FontConfig
// matches for non-fallback fonts might return 0. See isFallbackFontAllowed.
diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
index d7d224264..30d889f5c 100644
--- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
@@ -42,7 +42,9 @@
#include <cairo-ft.h>
#include <cairo.h>
#include <fontconfig/fcfreetype.h>
+#include <unicode/normlzr.h>
#include <wtf/MathExtras.h>
+#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -87,17 +89,16 @@ void SimpleFontData::platformDestroy()
{
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
ASSERT(m_platformData.scaledFont());
- return adoptPtr(new SimpleFontData(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
+ return SimpleFontData::create(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
scaleFactor * fontDescription.computedSize(),
m_platformData.syntheticBold(),
- m_platformData.syntheticOblique()),
- isCustomFont(), false));
+ m_platformData.syntheticOblique()), isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
@@ -105,17 +106,17 @@ SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
@@ -172,4 +173,33 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return w;
}
+#if USE(HARFBUZZ_NG)
+bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const
+{
+ if (!m_combiningCharacterSequenceSupport)
+ m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>);
+
+ WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false);
+ if (!addResult.isNewEntry)
+ return addResult.iterator->value;
+
+ UErrorCode error = U_ZERO_ERROR;
+ Vector<UChar, 4> normalizedCharacters(length);
+ int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
+ // Can't render if we have an error or no composition occurred.
+ if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length))
+ return false;
+
+ FT_Face face = cairo_ft_scaled_font_lock_face(m_platformData.scaledFont());
+ if (!face)
+ return false;
+
+ if (FcFreeTypeCharIndex(face, normalizedCharacters[0]))
+ addResult.iterator->value = true;
+
+ cairo_ft_scaled_font_unlock_face(m_platformData.scaledFont());
+ return addResult.iterator->value;
+}
+#endif
+
}
diff --git a/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp b/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp
index 9540b86a0..31f32cf0b 100644
--- a/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp
+++ b/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp
@@ -27,71 +27,9 @@
namespace WebCore {
-// We do not want to call glXMakeContextCurrent using different Display pointers,
-// because it might lead to crashes in some drivers (fglrx). We use a shared display
-// pointer here.
-static Display* gSharedDisplay = 0;
-Display* GLContextGLX::sharedDisplay()
-{
- if (!gSharedDisplay)
- gSharedDisplay = XOpenDisplay(0);
- return gSharedDisplay;
-}
-
-// Because of driver bugs, exiting the program when there are active pbuffers
-// can crash the X server (this has been observed with the official Nvidia drivers).
-// We need to ensure that we clean everything up on exit. There are several reasons
-// that GraphicsContext3Ds will still be alive at exit, including user error (memory
-// leaks) and the page cache. In any case, we don't want the X server to crash.
-typedef Vector<GLContext*> ActiveContextList;
-static ActiveContextList& activeContextList()
-{
- DEFINE_STATIC_LOCAL(ActiveContextList, activeContexts, ());
- return activeContexts;
-}
-
-void GLContextGLX::addActiveContext(GLContextGLX* context)
-{
- static bool addedAtExitHandler = false;
- if (!addedAtExitHandler) {
- atexit(&GLContextGLX::cleanupActiveContextsAtExit);
- addedAtExitHandler = true;
- }
- activeContextList().append(context);
-}
-
-static bool gCleaningUpAtExit = false;
-
-void GLContextGLX::removeActiveContext(GLContext* context)
-{
- // If we are cleaning up the context list at exit, don't bother removing the context
- // from the list, since we don't want to modify the list while it's being iterated.
- if (gCleaningUpAtExit)
- return;
-
- ActiveContextList& contextList = activeContextList();
- size_t i = contextList.find(context);
- if (i != notFound)
- contextList.remove(i);
-}
-
-void GLContextGLX::cleanupActiveContextsAtExit()
-{
- gCleaningUpAtExit = true;
-
- ActiveContextList& contextList = activeContextList();
- for (size_t i = 0; i < contextList.size(); ++i)
- delete contextList[i];
-
- if (!gSharedDisplay)
- return;
- XCloseDisplay(gSharedDisplay);
- gSharedDisplay = 0;
-}
-
PassOwnPtr<GLContextGLX> GLContextGLX::createWindowContext(XID window, GLContext* sharingContext)
{
- Display* display = sharedDisplay();
+ Display* display = sharedX11Display();
XWindowAttributes attributes;
if (!XGetWindowAttributes(display, window, &attributes))
return nullptr;
@@ -130,7 +68,7 @@ PassOwnPtr<GLContextGLX> GLContextGLX::createPbufferContext(GLXContext sharingCo
};
int returnedElements;
- Display* display = sharedDisplay();
+ Display* display = sharedX11Display();
GLXFBConfig* configs = glXChooseFBConfig(display, 0, fbConfigAttributes, &returnedElements);
if (!returnedElements) {
XFree(configs);
@@ -170,7 +108,7 @@ PassOwnPtr<GLContextGLX> GLContextGLX::createPixmapContext(GLXContext sharingCon
0
};
- Display* display = sharedDisplay();
+ Display* display = sharedX11Display();
XVisualInfo* visualInfo = glXChooseVisual(display, DefaultScreen(display), visualAttributes);
if (!visualInfo)
return nullptr;
@@ -200,7 +138,7 @@ PassOwnPtr<GLContextGLX> GLContextGLX::createPixmapContext(GLXContext sharingCon
PassOwnPtr<GLContextGLX> GLContextGLX::createContext(XID window, GLContext* sharingContext)
{
- if (!sharedDisplay())
+ if (!sharedX11Display())
return nullptr;
static bool initialized = false;
@@ -231,7 +169,6 @@ GLContextGLX::GLContextGLX(GLXContext context)
, m_pixmap(0)
, m_glxPixmap(0)
{
- addActiveContext(this);
}
GLContextGLX::GLContextGLX(GLXContext context, Pixmap pixmap, GLXPixmap glxPixmap)
@@ -241,7 +178,6 @@ GLContextGLX::GLContextGLX(GLXContext context, Pixmap pixmap, GLXPixmap glxPixma
, m_pixmap(pixmap)
, m_glxPixmap(glxPixmap)
{
- addActiveContext(this);
}
GLContextGLX::~GLContextGLX()
@@ -250,23 +186,22 @@ GLContextGLX::~GLContextGLX()
// This may be necessary to prevent crashes with NVidia's closed source drivers. Originally
// from Mozilla's 3D canvas implementation at: http://bitbucket.org/ilmari/canvas3d/
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- glXMakeCurrent(sharedDisplay(), None, None);
- glXDestroyContext(sharedDisplay(), m_context);
+ glXMakeCurrent(sharedX11Display(), None, None);
+ glXDestroyContext(sharedX11Display(), m_context);
}
if (m_pbuffer) {
- glXDestroyPbuffer(sharedDisplay(), m_pbuffer);
+ glXDestroyPbuffer(sharedX11Display(), m_pbuffer);
m_pbuffer = 0;
}
if (m_glxPixmap) {
- glXDestroyGLXPixmap(sharedDisplay(), m_glxPixmap);
+ glXDestroyGLXPixmap(sharedX11Display(), m_glxPixmap);
m_glxPixmap = 0;
}
if (m_pixmap) {
- XFreePixmap(sharedDisplay(), m_pixmap);
+ XFreePixmap(sharedX11Display(), m_pixmap);
m_pixmap = 0;
}
- removeActiveContext(this);
}
bool GLContextGLX::canRenderToDefaultFramebuffer()
@@ -282,7 +217,7 @@ IntSize GLContextGLX::defaultFrameBufferSize()
int x, y;
Window rootWindow;
unsigned int width, height, borderWidth, depth;
- if (!XGetGeometry(sharedDisplay(), m_window, &rootWindow, &x, &y, &width, &height, &borderWidth, &depth))
+ if (!XGetGeometry(sharedX11Display(), m_window, &rootWindow, &x, &y, &width, &height, &borderWidth, &depth))
return IntSize();
return IntSize(width, height);
@@ -297,18 +232,23 @@ bool GLContextGLX::makeContextCurrent()
return true;
if (m_window)
- return glXMakeCurrent(sharedDisplay(), m_window, m_context);
+ return glXMakeCurrent(sharedX11Display(), m_window, m_context);
if (m_pbuffer)
- return glXMakeCurrent(sharedDisplay(), m_pbuffer, m_context);
+ return glXMakeCurrent(sharedX11Display(), m_pbuffer, m_context);
- return ::glXMakeCurrent(sharedDisplay(), m_glxPixmap, m_context);
+ return ::glXMakeCurrent(sharedX11Display(), m_glxPixmap, m_context);
}
void GLContextGLX::swapBuffers()
{
if (m_window)
- glXSwapBuffers(sharedDisplay(), m_window);
+ glXSwapBuffers(sharedX11Display(), m_window);
+}
+
+void GLContextGLX::waitNative()
+{
+ glXWaitX();
}
#if USE(3D_GRAPHICS)
diff --git a/Source/WebCore/platform/graphics/glx/GLContextGLX.h b/Source/WebCore/platform/graphics/glx/GLContextGLX.h
index b3b18c156..00f56e791 100644
--- a/Source/WebCore/platform/graphics/glx/GLContextGLX.h
+++ b/Source/WebCore/platform/graphics/glx/GLContextGLX.h
@@ -25,7 +25,6 @@
#include "GLContext.h"
typedef struct __GLXcontextRec* GLXContext;
-typedef struct _XDisplay Display;
typedef struct __GLXcontextRec *GLXContext;
typedef unsigned long GLXPbuffer;
typedef unsigned long GLXPixmap;
@@ -45,11 +44,10 @@ public:
virtual ~GLContextGLX();
virtual bool makeContextCurrent();
virtual void swapBuffers();
+ virtual void waitNative();
virtual bool canRenderToDefaultFramebuffer();
virtual IntSize defaultFrameBufferSize();
- static Display* sharedDisplay();
-
#if USE(3D_GRAPHICS)
virtual PlatformGraphicsContext3D platformContext();
#endif
@@ -57,10 +55,6 @@ public:
private:
static PassOwnPtr<GLContextGLX> createPbufferContext(GLXContext sharingContext);
static PassOwnPtr<GLContextGLX> createPixmapContext(GLXContext sharingContext);
- static void removeActiveContext(GLContext*);
-
- static void addActiveContext(GLContextGLX*);
- static void cleanupActiveContextsAtExit();
GLContextGLX(GLXContext);
GLContextGLX(GLXContext, Pixmap, GLXPixmap);
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index fe51104f0..282bde03f 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -54,7 +54,10 @@ static const float s_resourceAdjustedRatio = 0.5;
PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size, PreserveDrawingBuffer preserve, AlphaRequirement alpha)
{
Extensions3D* extensions = context->getExtensions();
- bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample") && extensions->supports("GL_OES_rgb8_rgba8");
+ bool multisampleSupported = extensions->maySupportMultisampling()
+ && extensions->supports("GL_ANGLE_framebuffer_blit")
+ && extensions->supports("GL_ANGLE_framebuffer_multisample")
+ && extensions->supports("GL_OES_rgb8_rgba8");
if (multisampleSupported) {
extensions->ensureEnabled("GL_ANGLE_framebuffer_blit");
extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
index 9904242e4..b2c59aae6 100644
--- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
+++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
@@ -32,9 +32,9 @@
#define DrawingBuffer_h
#include "GraphicsContext3D.h"
-#include "GraphicsLayer.h"
#include "GraphicsTypes3D.h"
#include "IntSize.h"
+#include "PlatformLayer.h"
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
index 37468bc5c..deeb339d2 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp
@@ -86,6 +86,12 @@ template <> void derefGPtr<GstPadTemplate>(GstPadTemplate* ptr)
gst_object_unref(GST_OBJECT(ptr));
}
+template <> GRefPtr<GstCaps> adoptGRef(GstCaps* ptr)
+{
+ ASSERT(!ptr || !gstObjectIsFloating(GST_OBJECT(ptr)));
+ return GRefPtr<GstCaps>(ptr, GRefPtrAdopt);
+}
+
template <> GstCaps* refGPtr<GstCaps>(GstCaps* ptr)
{
if (ptr)
diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
index a3dcda8ae..5b0ed0db2 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h
@@ -45,6 +45,7 @@ template<> GRefPtr<GstPadTemplate> adoptGRef(GstPadTemplate* ptr);
template<> GstPadTemplate* refGPtr<GstPadTemplate>(GstPadTemplate* ptr);
template<> void derefGPtr<GstPadTemplate>(GstPadTemplate* ptr);
+template<> GRefPtr<GstCaps> adoptGRef(GstCaps* ptr);
template<> GstCaps* refGPtr<GstCaps>(GstCaps* ptr);
template<> void derefGPtr<GstCaps>(GstCaps* ptr);
diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
index 3c3f367b9..638f480ff 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
@@ -34,20 +34,19 @@ void webkitGstObjectRefSink(GstObject* gstObject)
#endif
}
-GstCaps* webkitGstGetPadCaps(GstPad* pad)
+GRefPtr<GstCaps> webkitGstGetPadCaps(GstPad* pad)
{
if (!pad)
return 0;
- GstCaps* caps;
#ifdef GST_API_VERSION_1
- caps = gst_pad_get_current_caps(pad);
+ GstCaps* caps = gst_pad_get_current_caps(pad);
if (!caps)
caps = gst_pad_query_caps(pad, 0);
+ return adoptGRef(caps); // gst_pad_query_caps and gst_pad_get_current_caps return a new reference.
#else
- caps = GST_PAD_CAPS(pad);
+ return GST_PAD_CAPS(pad);
#endif
- return caps;
}
bool getVideoSizeAndFormatFromCaps(GstCaps* caps, WebCore::IntSize& size, GstVideoFormat& format, int& pixelAspectRatioNumerator, int& pixelAspectRatioDenominator, int& stride)
diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h b/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
index a8e5182f6..2ecf08cef 100644
--- a/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
+++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
@@ -20,6 +20,7 @@
#ifndef GStreamerVersioning_h
#define GStreamerVersioning_h
+#include "GRefPtrGStreamer.h"
#include <gst/gst.h>
#include <gst/video/video.h>
@@ -28,7 +29,7 @@ class IntSize;
};
void webkitGstObjectRefSink(GstObject*);
-GstCaps* webkitGstGetPadCaps(GstPad*);
+GRefPtr<GstCaps> webkitGstGetPadCaps(GstPad*);
bool getVideoSizeAndFormatFromCaps(GstCaps*, WebCore::IntSize&, GstVideoFormat&, int& pixelAspectRatioNumerator, int& pixelAspectRatioDenominator, int& stride);
GstBuffer* createGstBuffer(GstBuffer*);
void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author);
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index 7a0e5ee56..83bdfe2b7 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -29,10 +29,6 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#if PLATFORM(QT)
-#include <QImage>
-#endif
-
namespace WebCore {
class IntSize;
diff --git a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
index d6e6e2afc..375026d1f 100644
--- a/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerQt.cpp
@@ -67,8 +67,9 @@ ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
image.invertPixels(invertMode);
#endif
-
- m_image = BitmapImage::create(new QImage(image));
+ QPixmap* surface = new QPixmap;
+ surface->convertFromImage(image);
+ m_image = BitmapImage::create(surface);
#ifdef GST_API_VERSION_1
if (GstVideoCropMeta* cropMeta = gst_buffer_get_video_crop_meta(buffer))
diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 6f5736baa..a4d47451d 100644
--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -540,7 +540,7 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
if (!m_videoSize.isEmpty())
return m_videoSize;
- GstCaps* caps = webkitGstGetPadCaps(m_videoSinkPad.get());
+ GRefPtr<GstCaps> caps = webkitGstGetPadCaps(m_videoSinkPad.get());
if (!caps)
return IntSize();
@@ -555,7 +555,7 @@ IntSize MediaPlayerPrivateGStreamer::naturalSize() const
int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
IntSize originalSize;
GstVideoFormat format;
- if (!getVideoSizeAndFormatFromCaps(caps, originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))
+ if (!getVideoSizeAndFormatFromCaps(caps.get(), originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))
return IntSize();
LOG_MEDIA_MESSAGE("Original video size: %dx%d", originalSize.width(), originalSize.height());
@@ -1566,11 +1566,11 @@ void MediaPlayerPrivateGStreamer::paint(GraphicsContext* context, const IntRect&
if (!m_buffer)
return;
- GstCaps* caps = webkitGstGetPadCaps(m_videoSinkPad.get());
+ GRefPtr<GstCaps> caps = webkitGstGetPadCaps(m_videoSinkPad.get());
if (!caps)
return;
- RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer, caps);
+ RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer, caps.get());
if (!gstImage)
return;
diff --git a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
index c2c0bd4e4..d852184c0 100644
--- a/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
+++ b/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
@@ -29,6 +29,7 @@
#if USE(GSTREAMER)
#include "VideoSinkGStreamer.h"
+#include "GRefPtrGStreamer.h"
#include "GStreamerVersioning.h"
#include "IntSize.h"
#include <glib.h>
@@ -172,27 +173,20 @@ static GstFlowReturn webkitVideoSinkRender(GstBaseSink* baseSink, GstBuffer* buf
gst_buffer_set_caps(priv->buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(baseSink)));
}
- GstCaps* caps = GST_BUFFER_CAPS(buffer);
+ GRefPtr<GstCaps> caps = GST_BUFFER_CAPS(buffer);
#else
- GstCaps* caps = gst_video_info_to_caps(&priv->info);
+ GRefPtr<GstCaps> caps = adoptGRef(gst_video_info_to_caps(&priv->info));
#endif
GstVideoFormat format;
WebCore::IntSize size;
int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
- if (!getVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride)) {
+ if (!getVideoSizeAndFormatFromCaps(caps.get(), size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride)) {
gst_buffer_unref(buffer);
-#ifdef GST_API_VERSION_1
- gst_caps_unref(caps);
-#endif
g_mutex_unlock(priv->bufferMutex);
return GST_FLOW_ERROR;
}
-#ifdef GST_API_VERSION_1
- gst_caps_unref(caps);
-#endif
-
// Cairo's ARGB has pre-multiplied alpha while GStreamer's doesn't.
// Here we convert to Cairo's ARGB.
if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA) {
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp b/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
index 9401b0135..8a4d8720c 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
@@ -70,8 +70,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
// padding and fallback if we find that we are wrong.
createGlyphArrays((m_normalizedBufferLength + 2) * 2);
- m_item.log_clusters = new unsigned short[m_normalizedBufferLength];
-
m_item.face = 0;
m_item.font = allocHarfbuzzFont();
@@ -90,7 +88,6 @@ ComplexTextController::~ComplexTextController()
{
fastFree(m_item.font);
deleteGlyphArrays();
- delete[] m_item.log_clusters;
}
void ComplexTextController::reset(int offset)
@@ -299,6 +296,7 @@ void ComplexTextController::deleteGlyphArrays()
delete[] m_item.attributes;
delete[] m_item.advances;
delete[] m_item.offsets;
+ delete[] m_item.log_clusters;
delete[] m_glyphs16;
delete[] m_positions;
}
@@ -309,6 +307,7 @@ void ComplexTextController::createGlyphArrays(int size)
m_item.attributes = new HB_GlyphAttributes[size];
m_item.advances = new HB_Fixed[size];
m_item.offsets = new HB_FixedPoint[size];
+ m_item.log_clusters = new unsigned short[size];
m_glyphs16 = new uint16_t[size];
m_positions = new SkPoint[size];
diff --git a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp
index 2d9e86a35..b9d5fc8e8 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp
@@ -350,16 +350,12 @@ static SkFontTableTag reverseByteOrder(uint32_t tableTag)
const OpenTypeVerticalData* FontPlatformData::verticalData() const
{
- if (!uniqueID())
- return 0;
return fontCache()->getVerticalData(uniqueID(), *this);
}
PassRefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
{
RefPtr<SharedBuffer> buffer;
- if (!uniqueID())
- return buffer.release();
SkFontTableTag tag = reverseByteOrder(table);
const size_t tableSize = SkFontHost::GetTableSize(uniqueID(), tag);
diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzSkia.cpp b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzSkia.cpp
index f68ea6192..1e8867bb7 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzSkia.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzSkia.cpp
@@ -244,18 +244,18 @@ static HB_FaceRec_* getCachedHarfbuzzFace(FontPlatformData* platformData)
gHarfbuzzFaceCache->set(uniqueID, entry);
return entry.first;
}
- ++(result.get()->second.second);
- return result.get()->second.first;
+ ++(result.get()->value.second);
+ return result.get()->value.first;
}
static void releaseCachedHarfbuzzFace(SkFontID uniqueID)
{
HarfbuzzFaceCache::iterator result = gHarfbuzzFaceCache->find(uniqueID);
ASSERT(result != gHarfbuzzFaceCache->end());
- ASSERT(result.get()->second.second > 0);
- --(result.get()->second.second);
- if (!(result.get()->second.second)) {
- HB_FreeFace(result.get()->second.first);
+ ASSERT(result.get()->value.second > 0);
+ --(result.get()->value.second);
+ if (!(result.get()->value.second)) {
+ HB_FreeFace(result.get()->value.first);
gHarfbuzzFaceCache->remove(uniqueID);
}
}
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp
index 7dd048b3b..50dbd81bd 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.cpp
@@ -32,17 +32,44 @@
#include "HarfBuzzNGFace.h"
#include "FontPlatformData.h"
+#include "hb-ot.h"
#include "hb.h"
-#include <wtf/HashMap.h>
namespace WebCore {
+const hb_tag_t HarfBuzzNGFace::vertTag = HB_TAG('v', 'e', 'r', 't');
+const hb_tag_t HarfBuzzNGFace::vrt2Tag = HB_TAG('v', 'r', 't', '2');
+
// Though we have FontCache class, which provides the cache mechanism for
// WebKit's font objects, we also need additional caching layer for HarfBuzz
// to reduce the memory consumption because hb_face_t should be associated with
// underling font data (e.g. CTFontRef, FTFace).
-typedef pair<hb_face_t*, unsigned> FaceCacheEntry;
-typedef HashMap<uint64_t, FaceCacheEntry, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t> > HarfBuzzNGFaceCache;
+
+class FaceCacheEntry : public RefCounted<FaceCacheEntry> {
+public:
+ static PassRefPtr<FaceCacheEntry> create(hb_face_t* face)
+ {
+ ASSERT(face);
+ return adoptRef(new FaceCacheEntry(face));
+ }
+ ~FaceCacheEntry()
+ {
+ hb_face_destroy(m_face);
+ }
+
+ hb_face_t* face() { return m_face; }
+ HashMap<uint32_t, uint16_t>* glyphCache() { return &m_glyphCache; }
+
+private:
+ explicit FaceCacheEntry(hb_face_t* face)
+ : m_face(face)
+ { }
+
+ hb_face_t* m_face;
+ HashMap<uint32_t, uint16_t> m_glyphCache;
+};
+
+typedef HashMap<uint64_t, RefPtr<FaceCacheEntry>, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t> > HarfBuzzNGFaceCache;
static HarfBuzzNGFaceCache* harfbuzzFaceCache()
{
@@ -53,28 +80,52 @@ static HarfBuzzNGFaceCache* harfbuzzFaceCache()
HarfBuzzNGFace::HarfBuzzNGFace(FontPlatformData* platformData, uint64_t uniqueID)
: m_platformData(platformData)
, m_uniqueID(uniqueID)
+ , m_scriptForVerticalText(HB_SCRIPT_INVALID)
{
- HarfBuzzNGFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID);
- if (result == harfbuzzFaceCache()->end()) {
- m_face = createFace();
- ASSERT(m_face);
- harfbuzzFaceCache()->set(m_uniqueID, FaceCacheEntry(m_face, 1));
- } else {
- ++(result.get()->second.second);
- m_face = result.get()->second.first;
- }
+ HarfBuzzNGFaceCache::AddResult result = harfbuzzFaceCache()->add(m_uniqueID, 0);
+ if (result.isNewEntry)
+ result.iterator->value = FaceCacheEntry::create(createFace());
+ result.iterator->value->ref();
+ m_face = result.iterator->value->face();
+ m_glyphCacheForFaceCacheEntry = result.iterator->value->glyphCache();
}
HarfBuzzNGFace::~HarfBuzzNGFace()
{
HarfBuzzNGFaceCache::iterator result = harfbuzzFaceCache()->find(m_uniqueID);
ASSERT(result != harfbuzzFaceCache()->end());
- ASSERT(result.get()->second.second > 0);
- --(result.get()->second.second);
- if (!(result.get()->second.second)) {
- hb_face_destroy(result.get()->second.first);
+ ASSERT(result.get()->value->refCount() > 1);
+ result.get()->value->deref();
+ if (result.get()->value->refCount() == 1)
harfbuzzFaceCache()->remove(m_uniqueID);
+}
+
+static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face)
+{
+ static const unsigned maxCount = 32;
+
+ unsigned scriptCount = maxCount;
+ hb_tag_t scriptTags[maxCount];
+ hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags);
+ for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) {
+ unsigned languageCount = maxCount;
+ hb_tag_t languageTags[maxCount];
+ hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags);
+ for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) {
+ unsigned featureIndex;
+ if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzNGFace::vertTag, &featureIndex)
+ || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzNGFace::vrt2Tag, &featureIndex))
+ return hb_ot_tag_to_script(scriptTags[scriptIndex]);
+ }
}
+ return HB_SCRIPT_INVALID;
+}
+
+void HarfBuzzNGFace::setScriptForVerticalGlyphSubstitution(hb_buffer_t* buffer)
+{
+ if (m_scriptForVerticalText == HB_SCRIPT_INVALID)
+ m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_face);
+ hb_buffer_set_script(buffer, m_scriptForVerticalText);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h
index cbc8f8ed4..360daf9cf 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h
@@ -33,6 +33,7 @@
#include <hb.h>
+#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -43,6 +44,9 @@ class FontPlatformData;
class HarfBuzzNGFace : public RefCounted<HarfBuzzNGFace> {
public:
+ static const hb_tag_t vertTag;
+ static const hb_tag_t vrt2Tag;
+
static PassRefPtr<HarfBuzzNGFace> create(FontPlatformData* platformData, uint64_t uniqueID)
{
return adoptRef(new HarfBuzzNGFace(platformData, uniqueID));
@@ -51,6 +55,8 @@ public:
hb_font_t* createFont();
+ void setScriptForVerticalGlyphSubstitution(hb_buffer_t*);
+
private:
HarfBuzzNGFace(FontPlatformData*, uint64_t);
@@ -59,6 +65,9 @@ private:
FontPlatformData* m_platformData;
uint64_t m_uniqueID;
hb_face_t* m_face;
+ WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry;
+
+ hb_script_t m_scriptForVerticalText;
};
}
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp
index 52fca7baf..2db3d2780 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp
@@ -155,9 +155,7 @@ static hb_font_funcs_t* harfbuzzCairoTextGetFontFuncs()
static hb_blob_t* harfbuzzCairoGetTable(hb_face_t*, hb_tag_t tag, void* userData)
{
- FontPlatformData* font = reinterpret_cast<FontPlatformData*>(userData);
-
- cairo_scaled_font_t* scaledFont = font->scaledFont();
+ cairo_scaled_font_t* scaledFont = reinterpret_cast<cairo_scaled_font_t*>(userData);
if (!scaledFont)
return 0;
@@ -186,7 +184,7 @@ static hb_blob_t* harfbuzzCairoGetTable(hb_face_t*, hb_tag_t tag, void* userData
hb_face_t* HarfBuzzNGFace::createFace()
{
- hb_face_t* face = hb_face_create_for_tables(harfbuzzCairoGetTable, m_platformData, 0);
+ hb_face_t* face = hb_face_create_for_tables(harfbuzzCairoGetTable, m_platformData->scaledFont(), 0);
ASSERT(face);
return face;
}
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp
index f2baba73f..e4c65cd41 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp
@@ -108,10 +108,7 @@ static void releaseTableData(void* userData)
static hb_blob_t* harfbuzzCoreTextGetTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
- FontPlatformData* platformData = reinterpret_cast<FontPlatformData*>(userData);
- // It seems that CTFontCopyTable of MacOSX10.5 sdk doesn't work for
- // OpenType layout tables(GDEF, GSUB, GPOS). Use CGFontCopyTableForTag instead.
- CGFontRef cgFont = platformData->cgFont();
+ CGFontRef cgFont = reinterpret_cast<CGFontRef>(userData);
CFDataRef cfData = CGFontCopyTableForTag(cgFont, tag);
if (!cfData)
return 0;
@@ -125,7 +122,9 @@ static hb_blob_t* harfbuzzCoreTextGetTable(hb_face_t* face, hb_tag_t tag, void*
hb_face_t* HarfBuzzNGFace::createFace()
{
- hb_face_t* face = hb_face_create_for_tables(harfbuzzCoreTextGetTable, m_platformData, 0);
+ // It seems that CTFontCopyTable of MacOSX10.5 sdk doesn't work for
+ // OpenType layout tables(GDEF, GSUB, GPOS). Use CGFontCopyTableForTag instead.
+ hb_face_t* face = hb_face_create_for_tables(harfbuzzCoreTextGetTable, m_platformData->cgFont(), 0);
ASSERT(face);
return face;
}
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp
index 53acb292c..5d39efa73 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp
@@ -43,12 +43,21 @@
#include "SkUtils.h"
#include "hb.h"
+#include <wtf/HashMap.h>
namespace WebCore {
// Our implementation of the callbacks which Harfbuzz requires by using Skia
// calls. See the Harfbuzz source for references about what these callbacks do.
+struct HarfBuzzFontData {
+ HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEntry)
+ : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry)
+ { }
+ SkPaint m_paint;
+ WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry;
+};
+
static hb_position_t SkiaScalarToHarfbuzzPosition(SkScalar value)
{
return SkScalarToFixed(value);
@@ -56,8 +65,7 @@ static hb_position_t SkiaScalarToHarfbuzzPosition(SkScalar value)
static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint, hb_position_t* width, hb_glyph_extents_t* extents)
{
- if (codepoint > 0xFFFF)
- return;
+ ASSERT(codepoint <= 0xFFFF);
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
SkScalar skWidth;
@@ -78,23 +86,27 @@ static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint
static hb_bool_t harfbuzzGetGlyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData)
{
- SkPaint* paint = reinterpret_cast<SkPaint*>(fontData);
-
- paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
- uint16_t text[4];
- size_t length = SkUTF16_FromUnichar(unicode, text);
- uint16_t glyph16;
- paint->textToGlyphs(text, length, &glyph16);
- *glyph = glyph16;
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
+
+ WTF::HashMap<uint32_t, uint16_t>::AddResult result = hbFontData->m_glyphCacheForFaceCacheEntry->add(unicode, 0);
+ if (result.isNewEntry) {
+ SkPaint* paint = &hbFontData->m_paint;
+ paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
+ uint16_t glyph16;
+ paint->textToGlyphs(&unicode, sizeof(hb_codepoint_t), &glyph16);
+ result.iterator->value = glyph16;
+ *glyph = glyph16;
+ }
+ *glyph = result.iterator->value;
return !!*glyph;
}
static hb_position_t harfbuzzGetGlyphHorizontalAdvance(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, void* userData)
{
- SkPaint* paint = reinterpret_cast<SkPaint*>(fontData);
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
hb_position_t advance = 0;
- SkiaGetGlyphWidthAndExtents(paint, glyph, &advance, 0);
+ SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, &advance, 0);
return advance;
}
@@ -107,9 +119,9 @@ static hb_bool_t harfbuzzGetGlyphHorizontalOrigin(hb_font_t* hbFont, void* fontD
static hb_bool_t harfbuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void* userData)
{
- SkPaint* paint = reinterpret_cast<SkPaint*>(fontData);
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
- SkiaGetGlyphWidthAndExtents(paint, glyph, 0, extents);
+ SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, 0, extents);
return true;
}
@@ -132,16 +144,16 @@ static hb_font_funcs_t* harfbuzzSkiaGetFontFuncs()
static hb_blob_t* harfbuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
- FontPlatformData* font = reinterpret_cast<FontPlatformData*>(userData);
+ SkFontID uniqueID = static_cast<SkFontID>(reinterpret_cast<uint64_t>(userData));
- const size_t tableSize = SkFontHost::GetTableSize(font->uniqueID(), tag);
+ const size_t tableSize = SkFontHost::GetTableSize(uniqueID, tag);
if (!tableSize)
return 0;
char* buffer = reinterpret_cast<char*>(fastMalloc(tableSize));
if (!buffer)
return 0;
- size_t actualSize = SkFontHost::GetTableData(font->uniqueID(), tag, 0, tableSize, buffer);
+ size_t actualSize = SkFontHost::GetTableData(uniqueID, tag, 0, tableSize, buffer);
if (tableSize != actualSize) {
fastFree(buffer);
return 0;
@@ -151,25 +163,25 @@ static hb_blob_t* harfbuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* user
HB_MEMORY_MODE_WRITABLE, buffer, fastFree);
}
-static void destroyPaint(void* userData)
+static void destroyHarfBuzzFontData(void* userData)
{
- SkPaint* paint = reinterpret_cast<SkPaint*>(userData);
- delete paint;
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(userData);
+ delete hbFontData;
}
hb_face_t* HarfBuzzNGFace::createFace()
{
- hb_face_t* face = hb_face_create_for_tables(harfbuzzSkiaGetTable, m_platformData, 0);
+ hb_face_t* face = hb_face_create_for_tables(harfbuzzSkiaGetTable, reinterpret_cast<void*>(m_platformData->uniqueID()), 0);
ASSERT(face);
return face;
}
hb_font_t* HarfBuzzNGFace::createFont()
{
+ HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCacheEntry);
+ m_platformData->setupPaint(&hbFontData->m_paint);
hb_font_t* font = hb_font_create(m_face);
- SkPaint* paint = new SkPaint;
- m_platformData->setupPaint(paint);
- hb_font_set_funcs(font, harfbuzzSkiaGetFontFuncs(), paint, destroyPaint);
+ hb_font_set_funcs(font, harfbuzzSkiaGetFontFuncs(), hbFontData, destroyHarfBuzzFontData);
float size = m_platformData->size();
int scale = SkiaScalarToHarfbuzzPosition(size);
hb_font_set_scale(font, scale, scale);
diff --git a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
index 9e55fc411..796b37c95 100644
--- a/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
+++ b/Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp
@@ -87,10 +87,6 @@ void HarfBuzzShaper::HarfBuzzRun::applyShapeResult(hb_buffer_t* harfbuzzBuffer)
m_advances.resize(m_numGlyphs);
m_glyphToCharacterIndexes.resize(m_numGlyphs);
m_offsets.resize(m_numGlyphs);
-
- hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(harfbuzzBuffer, 0);
- for (unsigned i = 0; i < m_numGlyphs; ++i)
- m_glyphToCharacterIndexes[i] = infos[i].cluster;
}
void HarfBuzzShaper::HarfBuzzRun::setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, float offsetX, float offsetY)
@@ -204,18 +200,27 @@ void HarfBuzzShaper::setDrawRange(int from, int to)
void HarfBuzzShaper::setFontFeatures()
{
- FontFeatureSettings* settings = m_font->fontDescription().featureSettings();
+ const FontDescription& description = m_font->fontDescription();
+ if (description.orientation() == Vertical) {
+ static hb_feature_t vert = { HarfBuzzNGFace::vertTag, 1, 0, static_cast<unsigned>(-1) };
+ static hb_feature_t vrt2 = { HarfBuzzNGFace::vrt2Tag, 1, 0, static_cast<unsigned>(-1) };
+ m_features.append(vert);
+ m_features.append(vrt2);
+ }
+
+ FontFeatureSettings* settings = description.featureSettings();
if (!settings)
return;
unsigned numFeatures = settings->size();
- m_features.resize(numFeatures);
for (unsigned i = 0; i < numFeatures; ++i) {
+ hb_feature_t feature;
const UChar* tag = settings->at(i).tag().characters();
- m_features[i].tag = HB_TAG(tag[0], tag[1], tag[2], tag[3]);
- m_features[i].value = settings->at(i).value();
- m_features[i].start = 0;
- m_features[i].end = static_cast<unsigned>(-1);
+ feature.tag = HB_TAG(tag[0], tag[1], tag[2], tag[3]);
+ feature.value = settings->at(i).value();
+ feature.start = 0;
+ feature.end = static_cast<unsigned>(-1);
+ m_features.append(feature);
}
}
@@ -240,20 +245,6 @@ FloatPoint HarfBuzzShaper::adjustStartPoint(const FloatPoint& point)
return point + m_startOffset;
}
-static const SimpleFontData* fontDataForCombiningCharacterSequence(const Font* font, const UChar* characters, size_t length)
-{
- UErrorCode error = U_ZERO_ERROR;
- Vector<UChar, 4> normalizedCharacters(length);
- int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
- // Should fallback if we have an error or no composition occurred.
- if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length))
- return 0;
- UChar32 normalizedCharacter;
- size_t index = 0;
- U16_NEXT(&normalizedCharacters[0], index, static_cast<size_t>(normalizedLength), normalizedCharacter);
- return font->glyphDataForCharacter(normalizedCharacter, false).fontData;
-}
-
bool HarfBuzzShaper::collectHarfBuzzRuns()
{
const UChar* normalizedBufferEnd = m_normalizedBuffer.get() + m_normalizedBufferLength;
@@ -278,6 +269,7 @@ bool HarfBuzzShaper::collectHarfBuzzRuns()
for (iterator.advance(clusterLength); iterator.consume(character, clusterLength); iterator.advance(clusterLength)) {
if (Font::treatAsZeroWidthSpace(character))
continue;
+
if (U_GET_GC_MASK(character) & U_GC_M_MASK) {
int markLength = clusterLength;
const UChar* markCharactersEnd = iterator.characters() + clusterLength;
@@ -290,11 +282,12 @@ bool HarfBuzzShaper::collectHarfBuzzRuns()
markLength += nextCharacterLength;
markCharactersEnd += nextCharacterLength;
}
- nextFontData = fontDataForCombiningCharacterSequence(m_font, currentCharacterPosition, markCharactersEnd - currentCharacterPosition);
- if (nextFontData)
+
+ if (currentFontData->canRenderCombiningCharacterSequence(currentCharacterPosition, markCharactersEnd - currentCharacterPosition)) {
clusterLength = markLength;
- else
- nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
+ continue;
+ }
+ nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
} else
nextFontData = m_font->glyphDataForCharacter(character, false).fontData;
@@ -305,6 +298,7 @@ bool HarfBuzzShaper::collectHarfBuzzRuns()
break;
if (nextScript == USCRIPT_INHERITED)
nextScript = currentScript;
+ currentCharacterPosition = iterator.characters();
}
unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - startIndexOfCurrentRun;
m_harfbuzzRuns.append(HarfBuzzRun::create(currentFontData, startIndexOfCurrentRun, numCharactersOfCurrentRun, m_run.direction()));
@@ -340,7 +334,12 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns()
HarfBuzzNGFace* face = platformData->harfbuzzFace();
if (!face)
return false;
+
+ if (m_font->fontDescription().orientation() == Vertical)
+ face->setScriptForVerticalGlyphSubstitution(harfbuzzBuffer.get());
+
HarfBuzzScopedPtr<hb_font_t> harfbuzzFont(face->createFont(), hb_font_destroy);
+
hb_shape(harfbuzzFont.get(), harfbuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size());
currentRun->applyShapeResult(harfbuzzBuffer.get());
@@ -361,6 +360,7 @@ void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(harfbuzzBuffer, 0);
unsigned numGlyphs = currentRun->numGlyphs();
+ uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes();
float totalAdvance = 0;
// HarfBuzz returns the shaping result in visual order. We need not to flip for RTL.
@@ -374,6 +374,9 @@ void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
unsigned currentCharacterIndex = currentRun->startIndex() + glyphInfos[i].cluster;
bool isClusterEnd = runEnd || glyphInfos[i].cluster != glyphInfos[i + 1].cluster;
float spacing = 0;
+
+ glyphToCharacterIndexes[i] = glyphInfos[i].cluster;
+
if (isClusterEnd && !Font::treatAsZeroWidthSpace(m_normalizedBuffer[currentCharacterIndex]))
spacing += m_letterSpacing;
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 3553a9780..81cf10486 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -43,7 +43,7 @@ class TextLayout {
public:
static bool isNeeded(RenderText* text, const Font& font)
{
- TextRun run = RenderBlock::constructTextRun(text, font, text->characters(), text->textLength(), text->style());
+ TextRun run = RenderBlock::constructTextRun(text, font, text, text->style());
return font.codePath(run) == Font::Complex;
}
@@ -54,13 +54,13 @@ public:
{
}
- float width(unsigned from, unsigned len)
+ float width(unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts)
{
- m_controller->advance(from, 0, ByWholeGlyphs);
+ m_controller->advance(from, 0, ByWholeGlyphs, fallbackFonts);
float beforeWidth = m_controller->runWidthSoFar();
if (m_font.wordSpacing() && from && Font::treatAsSpace(m_run[from]))
beforeWidth += m_font.wordSpacing();
- m_controller->advance(from + len, 0, ByWholeGlyphs);
+ m_controller->advance(from + len, 0, ByWholeGlyphs, fallbackFonts);
float afterWidth = m_controller->runWidthSoFar();
return afterWidth - beforeWidth;
}
@@ -68,7 +68,7 @@ public:
private:
static TextRun constructTextRun(RenderText* text, const Font& font, float xPos)
{
- TextRun run = RenderBlock::constructTextRun(text, font, text->characters(), text->textLength(), text->style());
+ TextRun run = RenderBlock::constructTextRun(text, font, text, text->style());
run.setCharactersLength(text->textLength());
ASSERT(run.charactersLength() >= run.length());
@@ -94,9 +94,9 @@ void Font::deleteLayout(TextLayout* layout)
delete layout;
}
-float Font::width(TextLayout& layout, unsigned from, unsigned len)
+float Font::width(TextLayout& layout, unsigned from, unsigned len, HashSet<const SimpleFontData*>* fallbackFonts)
{
- return layout.width(from, len);
+ return layout.width(from, len, fallbackFonts);
}
static inline CGFloat roundCGFloat(CGFloat f)
@@ -142,7 +142,11 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
m_expansionPerOpportunity = 0;
else {
bool isAfterExpansion = m_afterExpansion;
- unsigned expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters16(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
+ unsigned expansionOpportunityCount;
+ if (m_run.is8Bit())
+ expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters8(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
+ else
+ expansionOpportunityCount = Font::expansionOpportunityCount(m_run.characters16(), m_end, m_run.ltr() ? LTR : RTL, isAfterExpansion);
if (isAfterExpansion && !m_run.allowsTrailingExpansion())
expansionOpportunityCount--;
@@ -284,7 +288,14 @@ void ComplexTextController::collectComplexTextRuns()
return;
// We break up glyph run generation for the string by FontData.
- const UChar* cp = m_run.characters16();
+ const UChar* cp;
+
+ if (m_run.is8Bit()) {
+ String stringFor8BitRun = String::make16BitFrom8BitSource(m_run.characters8(), m_run.length());
+ cp = stringFor8BitRun.characters16();
+ m_stringsFor8BitRuns.append(stringFor8BitRun);
+ } else
+ cp = m_run.characters16();
if (m_font.isSmallCaps())
m_smallCapsBuffer.resize(m_end);
@@ -449,7 +460,7 @@ unsigned ComplexTextController::incrementCurrentRun(unsigned& leftmostGlyph)
return indexOfCurrentRun(leftmostGlyph);
}
-void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle)
+void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle, HashSet<const SimpleFontData*>* fallbackFonts)
{
if (static_cast<int>(offset) > m_end)
offset = m_end;
@@ -474,6 +485,8 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, G
size_t glyphCount = complexTextRun.glyphCount();
unsigned g = ltr ? m_glyphInCurrentRun : glyphCount - 1 - m_glyphInCurrentRun;
unsigned k = leftmostGlyph + g;
+ if (fallbackFonts && complexTextRun.fontData() != m_font.primaryFont())
+ fallbackFonts->add(complexTextRun.fontData());
while (m_glyphInCurrentRun < glyphCount) {
unsigned glyphStartOffset = complexTextRun.indexAt(g);
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
index b3165c279..25c946ee3 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h
@@ -31,6 +31,7 @@
#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
#include <wtf/unicode/Unicode.h>
typedef unsigned short CGGlyph;
@@ -53,7 +54,7 @@ public:
ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, bool forTextEmphasis = false);
// Advance and emit glyphs up to the specified character.
- void advance(unsigned to, GlyphBuffer* = 0, GlyphIterationStyle = IncludePartialGlyphs);
+ void advance(unsigned to, GlyphBuffer* = 0, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const SimpleFontData*>* fallbackFonts = 0);
// Compute the character offset for a given x coordinate.
int offsetForPosition(float x, bool includePartialGlyphs);
@@ -143,6 +144,7 @@ private:
bool m_mayUseNaturalWritingDirection;
bool m_forTextEmphasis;
+ Vector<String> m_stringsFor8BitRuns;
Vector<UChar, 256> m_smallCapsBuffer;
// Retain lines rather than their runs for better performance.
diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
index 2440fd48e..f7d03110b 100644
--- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
+++ b/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
@@ -282,13 +282,13 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation + runRange.location, runRange.length, m_run.ltr()));
continue;
}
- runFontData = fontCache()->getCachedFontData(m_font.fontDescription(), fontName.get(), false, FontCache::DoNotRetain);
+ runFontData = fontCache()->getCachedFontData(m_font.fontDescription(), fontName.get(), false, FontCache::DoNotRetain).get();
#if !PLATFORM(WX)
// Core Text may have used a font that is not known to NSFontManager. In that case, fall back on
// using the font as returned, even though it may not have the best NSFontRenderingMode.
if (!runFontData) {
FontPlatformData runFontPlatformData((NSFont *)runFont, CTFontGetSize(runFont), m_font.fontDescription().usePrinterFont());
- runFontData = fontCache()->getCachedFontData(&runFontPlatformData, FontCache::DoNotRetain);
+ runFontData = fontCache()->getCachedFontData(&runFontPlatformData, FontCache::DoNotRetain).get();
}
#else
// just assert for now, until we can devise a better fix that works with wx.
diff --git a/Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp b/Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp
index dfdd8de22..e5c1ad364 100644
--- a/Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/DisplayRefreshMonitorMac.cpp
@@ -45,7 +45,7 @@ static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp* now, co
return kCVReturnSuccess;
}
-
+
DisplayRefreshMonitor::~DisplayRefreshMonitor()
{
if (m_displayLink) {
@@ -61,7 +61,7 @@ bool DisplayRefreshMonitor::requestRefreshCallback()
{
if (!m_active)
return false;
-
+
if (!m_displayLink) {
m_active = false;
CVReturn error = CVDisplayLinkCreateWithCGDisplay(m_displayID, &m_displayLink);
@@ -78,7 +78,7 @@ bool DisplayRefreshMonitor::requestRefreshCallback()
m_active = true;
}
-
+
MutexLocker lock(m_mutex);
m_scheduled = true;
return true;
@@ -92,9 +92,11 @@ void DisplayRefreshMonitor::displayLinkFired(double nowSeconds, double outputTim
m_previousFrameDone = false;
- double webKitNow = currentTime();
- m_timestamp = webKitNow - nowSeconds + outputTimeSeconds;
-
+ double webKitMonotonicNow = monotonicallyIncreasingTime();
+ double timeUntilOutput = outputTimeSeconds - nowSeconds;
+ // FIXME: Should this be using webKitMonotonicNow?
+ m_monotonicAnimationStartTime = webKitMonotonicNow + timeUntilOutput;
+
callOnMainThread(handleDisplayRefreshedNotificationOnMainThread, this);
}
diff --git a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
index 9b2555823..d1dc8162a 100644
--- a/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -99,7 +99,7 @@ static inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight)
return appKitFontWeight >= 7;
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
UChar32 character;
U16_GET(characters, 0, 0, length, character);
@@ -172,12 +172,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
return getCachedFontData(&alternateFont, DoNotRetain);
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
// Attempt to find an appropriate font using a match based on
// the presence of keywords in the the requested names. For example, we'll
// match any name that contains "Arabic" to Geeza Pro.
- SimpleFontData* simpleFontData = 0;
+ RefPtr<SimpleFontData> simpleFontData;
const FontFamily* currFamily = &font.fontDescription().family();
while (currFamily && !simpleFontData) {
if (currFamily->family().length()) {
@@ -190,18 +190,18 @@ SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
currFamily = currFamily->next();
}
- return simpleFontData;
+ return simpleFontData.release();
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
DEFINE_STATIC_LOCAL(AtomicString, timesStr, ("Times"));
// FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
// the default that the user would get without changing any prefs.
- SimpleFontData* simpleFontData = getCachedFontData(fontDescription, timesStr, false, shouldRetain);
+ RefPtr<SimpleFontData> simpleFontData = getCachedFontData(fontDescription, timesStr, false, shouldRetain);
if (simpleFontData)
- return simpleFontData;
+ return simpleFontData.release();
// The Times fallback will almost always work, but in the highly unusual case where
// the user doesn't have it, we fall back on Lucida Grande because that's
diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index b7acd83bc..da80c2bde 100644
--- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -91,8 +91,7 @@ float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int
if (run.rtl()) {
initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
- for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
- glyphBuffer.swap(i, end);
+ glyphBuffer.reverse(0, glyphBuffer.size());
} else
initialAdvance = beforeWidth;
@@ -189,21 +188,21 @@ const SimpleFontData* Font::fontDataForCombiningCharacterSequence(const UChar* c
if (simpleFontData->platformData().orientation() == Vertical) {
if (isCJKIdeographOrSymbol(baseCharacter) && !simpleFontData->hasVerticalGlyphs()) {
variant = BrokenIdeographVariant;
- simpleFontData = simpleFontData->brokenIdeographFontData();
+ simpleFontData = simpleFontData->brokenIdeographFontData().get();
} else if (m_fontDescription.textOrientation() == TextOrientationVerticalRight) {
- SimpleFontData* verticalRightFontData = simpleFontData->verticalRightOrientationFontData();
+ SimpleFontData* verticalRightFontData = simpleFontData->verticalRightOrientationFontData().get();
Glyph verticalRightGlyph = verticalRightFontData->glyphForCharacter(baseCharacter);
if (verticalRightGlyph == baseCharacterGlyphData.glyph)
simpleFontData = verticalRightFontData;
} else {
- SimpleFontData* uprightFontData = simpleFontData->uprightOrientationFontData();
+ SimpleFontData* uprightFontData = simpleFontData->uprightOrientationFontData().get();
Glyph uprightGlyph = uprightFontData->glyphForCharacter(baseCharacter);
if (uprightGlyph != baseCharacterGlyphData.glyph)
simpleFontData = uprightFontData;
}
}
} else {
- if (const SimpleFontData* variantFontData = simpleFontData->variantFontData(m_fontDescription, variant))
+ if (const SimpleFontData* variantFontData = simpleFontData->variantFontData(m_fontDescription, variant).get())
simpleFontData = variantFontData;
}
diff --git a/Source/WebCore/platform/graphics/mac/FontMac.mm b/Source/WebCore/platform/graphics/mac/FontMac.mm
index 608123cbd..b515f81d5 100644
--- a/Source/WebCore/platform/graphics/mac/FontMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontMac.mm
@@ -241,15 +241,15 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
float shadowTextX = point.x() + shadowOffset.width();
// If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
float shadowTextY = point.y() + shadowOffset.height() * (context->shadowsIgnoreTransforms() ? -1 : 1);
- showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
if (syntheticBoldOffset)
- showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
context->setFillColor(fillColor, fillColorSpace);
}
- showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
if (syntheticBoldOffset)
- showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
if (hasSimpleShadow)
context->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 68f4f2437..82538779c 100644
--- a/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -277,12 +277,6 @@ void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr<ErrorMessageCallback>
{
}
-void GraphicsContext3D::releaseShaderCompiler()
-{
- makeContextCurrent();
- notImplemented();
-}
-
}
#endif // USE(3D_GRAPHICS)
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 436160718..3ee1a4c29 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -76,6 +76,10 @@ private:
static PassOwnPtr<MediaPlayerPrivateInterface> create(MediaPlayer*);
static void getSupportedTypes(HashSet<String>& types);
static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs, const KURL&);
+#if ENABLE(ENCRYPTED_MEDIA)
+ static MediaPlayer::SupportsType extendedSupportsType(const String& type, const String& codecs, const String& keySystem, const KURL&);
+#endif
+
static void getSitesInMediaCache(Vector<String>&);
static void clearMediaCache();
static void clearMediaCacheForSite(const String&);
diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 2e849af61..c03eda9e4 100644
--- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -47,7 +47,7 @@
#import <wtf/UnusedParam.h>
#if USE(ACCELERATED_COMPOSITING)
-#include "GraphicsLayer.h"
+#include "PlatformLayer.h"
#endif
#if DRAW_FRAME_RATE
@@ -190,7 +190,11 @@ PassOwnPtr<MediaPlayerPrivateInterface> MediaPlayerPrivateQTKit::create(MediaPla
void MediaPlayerPrivateQTKit::registerMediaEngine(MediaEngineRegistrar registrar)
{
if (isAvailable())
+#if ENABLE(ENCRYPTED_MEDIA)
+ registrar(create, getSupportedTypes, extendedSupportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite);
+#else
registrar(create, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite);
+#endif
}
MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player)
@@ -1518,6 +1522,17 @@ MediaPlayer::SupportsType MediaPlayerPrivateQTKit::supportsType(const String& ty
return MediaPlayer::IsNotSupported;
}
+#if ENABLE(ENCRYPTED_MEDIA)
+MediaPlayer::SupportsType MediaPlayerPrivateQTKit::extendedSupportsType(const String& type, const String& codecs, const String& keySystem, const KURL& url)
+{
+ // QTKit does not support any encrytped media, so return IsNotSupported if the keySystem is non-NULL:
+ if (!keySystem.isNull() || !keySystem.isEmpty())
+ return MediaPlayer::IsNotSupported;
+
+ return supportsType(type, codecs, url);;
+}
+#endif
+
bool MediaPlayerPrivateQTKit::isAvailable()
{
// On 10.5 and higher, QuickTime will always be new enough for <video> and <audio> support, so we just check that the framework can be loaded.
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
index 05193742c..0b713347f 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
@@ -43,7 +43,7 @@ CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typese
{
unsigned key = typesettingFeatures + 1;
HashMap<unsigned, RetainPtr<CFDictionaryRef> >::AddResult addResult = m_CFStringAttributes.add(key, RetainPtr<CFDictionaryRef>());
- RetainPtr<CFDictionaryRef>& attributesDictionary = addResult.iterator->second;
+ RetainPtr<CFDictionaryRef>& attributesDictionary = addResult.iterator->value;
if (!addResult.isNewEntry)
return attributesDictionary.get();
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 66fe90a59..f8bb43ba7 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -308,19 +308,19 @@ void SimpleFontData::platformDestroy()
if (!isCustomFont() && m_derivedFontData) {
// These come from the cache.
if (m_derivedFontData->smallCaps)
- fontCache()->releaseFontData(m_derivedFontData->smallCaps.leakPtr());
+ fontCache()->releaseFontData(m_derivedFontData->smallCaps.get());
if (m_derivedFontData->emphasisMark)
- fontCache()->releaseFontData(m_derivedFontData->emphasisMark.leakPtr());
+ fontCache()->releaseFontData(m_derivedFontData->emphasisMark.get());
}
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
if (isCustomFont()) {
FontPlatformData scaledFontData(m_platformData);
scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
- return adoptPtr(new SimpleFontData(scaledFontData, true, false));
+ return SimpleFontData::create(scaledFontData, true, false);
}
BEGIN_BLOCK_OBJC_EXCEPTIONS;
@@ -345,31 +345,31 @@ PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
// SimpleFontData::platformDestroy() takes care of not deleting the cached font data twice.
- return adoptPtr(fontCache()->getCachedFontData(&scaledFontData));
+ return fontCache()->getCachedFontData(&scaledFontData);
}
END_BLOCK_OBJC_EXCEPTIONS;
- return nullptr;
+ return 0;
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFontSizeMultiplier);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5f);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
@@ -461,7 +461,7 @@ bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters
WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false);
if (!addResult.isNewEntry)
- return addResult.iterator->second;
+ return addResult.iterator->value;
RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(platformData().ctFont(), 0));
@@ -481,7 +481,7 @@ bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters
return false;
}
- addResult.iterator->second = true;
+ addResult.iterator->value = true;
return true;
}
diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.mm b/Source/WebCore/platform/graphics/mac/WebLayer.mm
index d783e494a..f89fec7f8 100644
--- a/Source/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebLayer.mm
@@ -109,7 +109,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA
// Re-fetch the layer owner, since <rdar://problem/9125151> indicates that it might have been destroyed during painting.
layerContents = platformLayer->owner();
ASSERT(layerContents);
- if (platformLayer->layerType() != PlatformCALayer::LayerTypeTileCacheLayer && layerContents && layerContents->platformCALayerShowRepaintCounter()) {
+ if (!platformLayer->usesTileCacheLayer() && layerContents && layerContents->platformCALayerShowRepaintCounter(platformLayer)) {
bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]];
char text[16]; // that's a lot of repaints
@@ -178,7 +178,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA
[super setNeedsDisplayInRect:dirtyRect];
- if (layerOwner->platformCALayerShowRepaintCounter()) {
+ if (layerOwner->platformCALayerShowRepaintCounter(platformLayer)) {
CGRect bounds = [self bounds];
CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 52, 27);
if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
diff --git a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
index 9736e74dc..65fa7d2ee 100644
--- a/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/Source/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -84,7 +84,7 @@ using namespace WebCore;
[super setNeedsDisplayInRect:dirtyRect];
- if (layerOwner->platformCALayerShowRepaintCounter()) {
+ if (layerOwner->platformCALayerShowRepaintCounter(platformLayer)) {
CGRect bounds = [self bounds];
CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 52, 27);
if (layerOwner->platformCALayerContentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
index 60f6bfaf3..aaf68d8be 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
@@ -46,6 +46,7 @@
#include "OpenGLShims.h"
#endif
+#include <wtf/MainThread.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -53,7 +54,46 @@ namespace WebCore {
Extensions3DOpenGLCommon::Extensions3DOpenGLCommon(GraphicsContext3D* context)
: m_initializedAvailableExtensions(false)
, m_context(context)
+ , m_isNVIDIA(false)
+ , m_isAMD(false)
+ , m_isIntel(false)
+ , m_maySupportMultisampling(true)
+ , m_requiresBuiltInFunctionEmulation(false)
{
+ m_vendor = String(reinterpret_cast<const char*>(::glGetString(GL_VENDOR)));
+
+ Vector<String> vendorComponents;
+ m_vendor.lower().split(' ', vendorComponents);
+ if (vendorComponents.contains("nvidia"))
+ m_isNVIDIA = true;
+ if (vendorComponents.contains("ati") || vendorComponents.contains("amd"))
+ m_isAMD = true;
+ if (vendorComponents.contains("intel"))
+ m_isIntel = true;
+
+#if PLATFORM(MAC)
+ if (m_isAMD || m_isIntel)
+ m_requiresBuiltInFunctionEmulation = true;
+
+ // Currently in Mac we only allow multisampling if the vendor is NVIDIA,
+ // or if the vendor is AMD/ATI and the system is 10.7.2 and above.
+
+ bool systemSupportsMultisampling = true;
+#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+ ASSERT(isMainThread());
+ static SInt32 version;
+ if (!version) {
+ if (Gestalt(gestaltSystemVersion, &version) != noErr)
+ systemSupportsMultisampling = false;
+ }
+ // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details
+ if (systemSupportsMultisampling)
+ systemSupportsMultisampling = version >= 0x1072;
+#endif // SNOW_LEOPARD and LION
+
+ if (m_isNVIDIA || (m_isAMD && systemSupportsMultisampling))
+ m_maySupportMultisampling = true;
+#endif
}
Extensions3DOpenGLCommon::~Extensions3DOpenGLCommon()
@@ -117,23 +157,28 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
if (result == m_context->m_shaderSourceMap.end())
return "";
- GraphicsContext3D::ShaderSourceEntry& entry = result->second;
+ GraphicsContext3D::ShaderSourceEntry& entry = result->value;
String translatedShaderSource;
String shaderInfoLog;
- int extraCompileOptions = 0;
+ int extraCompileOptions = SH_MAP_LONG_VARIABLE_NAMES;
-#if PLATFORM(MAC)
- const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
- if (vendor && (std::strstr(vendor, "ATI") || std::strstr(vendor, "AMD") || std::strstr(vendor, "Intel")))
+ if (m_requiresBuiltInFunctionEmulation)
extraCompileOptions |= SH_EMULATE_BUILT_IN_FUNCTIONS;
-#endif
- bool isValid = compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, extraCompileOptions);
+ Vector<ANGLEShaderSymbol> symbols;
+ bool isValid = compiler.compileShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog, symbols, extraCompileOptions);
entry.log = shaderInfoLog;
entry.isValid = isValid;
+ size_t numSymbols = symbols.size();
+ for (size_t i = 0; i < numSymbols; ++i) {
+ ANGLEShaderSymbol shaderSymbol = symbols[i];
+ GraphicsContext3D::SymbolInfo symbolInfo(shaderSymbol.dataType, shaderSymbol.size, shaderSymbol.mappedName);
+ entry.symbolMap(shaderSymbol.symbolType).set(shaderSymbol.name, symbolInfo);
+ }
+
if (!isValid)
return "";
diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
index 75869de19..7092cfaca 100644
--- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
+++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.h
@@ -57,6 +57,14 @@ public:
virtual void getnUniformfvEXT(GC3Duint program, int location, GC3Dsizei bufSize, float *params);
virtual void getnUniformivEXT(GC3Duint program, int location, GC3Dsizei bufSize, int *params);
+ virtual bool isNVIDIA() { return m_isNVIDIA; }
+ virtual bool isAMD() { return m_isAMD; }
+ virtual bool isIntel() { return m_isIntel; }
+ virtual String vendor() { return m_vendor; }
+
+ virtual bool maySupportMultisampling() { return m_maySupportMultisampling; }
+ virtual bool requiresBuiltInFunctionEmulation() { return m_requiresBuiltInFunctionEmulation; }
+
protected:
friend class Extensions3DOpenGLES;
Extensions3DOpenGLCommon(GraphicsContext3D*);
@@ -70,6 +78,14 @@ protected:
// Weak pointer back to GraphicsContext3D
GraphicsContext3D* m_context;
+
+ bool m_isNVIDIA;
+ bool m_isAMD;
+ bool m_isIntel;
+ bool m_maySupportMultisampling;
+ bool m_requiresBuiltInFunctionEmulation;
+
+ String m_vendor;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index 98e1145b3..d7c05e627 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -49,6 +49,12 @@
namespace WebCore {
+void GraphicsContext3D::releaseShaderCompiler()
+{
+ makeContextCurrent();
+ notImplemented();
+}
+
void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
{
::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
@@ -59,13 +65,7 @@ void GraphicsContext3D::validateAttributes()
Extensions3D* extensions = getExtensions();
validateDepthStencil("GL_EXT_packed_depth_stencil");
if (m_attrs.antialias) {
- bool isValidVendor = true;
- // Currently in Mac we only turn on antialias if vendor is NVIDIA,
- // or if ATI and on 10.7.2 and above.
- const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
- if (!vendor || (!std::strstr(vendor, "NVIDIA") && !(std::strstr(vendor, "ATI") && systemAllowsMultisamplingOnATICards())))
- isValidVendor = false;
- if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
+ if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
m_attrs.antialias = false;
else
extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
@@ -281,26 +281,6 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
::glClearDepth(depth);
}
-bool GraphicsContext3D::systemAllowsMultisamplingOnATICards() const
-{
-#if PLATFORM(MAC)
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
- return true;
-#else
- ASSERT(isMainThread());
- static SInt32 version;
- if (!version) {
- if (Gestalt(gestaltSystemVersion, &version) != noErr)
- return false;
- }
- // See https://bugs.webkit.org/show_bug.cgi?id=77922 for more details
- return version >= 0x1072;
-#endif // SNOW_LEOPARD and LION
-#else
- return false;
-#endif // PLATFORM(MAC)
-}
-
Extensions3D* GraphicsContext3D::getExtensions()
{
if (!m_extensions)
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
index 4fffee47d..db9fe43b6 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp
@@ -88,13 +88,7 @@ void GraphicsContext3D::validateDepthStencil(const char* packedDepthStencilExten
m_attrs.stencil = false;
}
if (m_attrs.antialias) {
- bool isValidVendor = true;
- // Currently in Mac we only turn on antialias if vendor is NVIDIA,
- // or if ATI and on 10.7.2 and above.
- const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR));
- if (!vendor || (!std::strstr(vendor, "NVIDIA") && !(std::strstr(vendor, "ATI") && systemAllowsMultisamplingOnATICards())))
- isValidVendor = false;
- if (!isValidVendor || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
+ if (!extensions->maySupportMultisampling() || !extensions->supports("GL_ANGLE_framebuffer_multisample") || isGLES2Compliant())
m_attrs.antialias = false;
else
extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample");
@@ -471,8 +465,8 @@ void GraphicsContext3D::compileShader(Platform3DObject shader)
::glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
if (length) {
- HashMap<Platform3DObject, GraphicsContext3D::ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
- GraphicsContext3D::ShaderSourceEntry& entry = result->second;
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
+ GraphicsContext3D::ShaderSourceEntry& entry = result->value;
GLsizei size = 0;
OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]);
@@ -483,9 +477,9 @@ void GraphicsContext3D::compileShader(Platform3DObject shader)
// ASSERT that ANGLE generated GLSL will be accepted by OpenGL.
ASSERT(GLCompileSuccess == GL_TRUE);
-#if PLATFORM(BLACKBERRY)
+#if PLATFORM(BLACKBERRY) && !defined(NDEBUG)
if (GLCompileSuccess != GL_TRUE)
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n");
+ BBLOG(BlackBerry::Platform::LogLevelWarn, "The shader validated, but didn't compile.\n");
#endif
}
@@ -635,7 +629,10 @@ bool GraphicsContext3D::getActiveAttrib(Platform3DObject program, GC3Duint index
::glGetActiveAttrib(program, index, maxAttributeSize, &nameLength, &size, &type, name.get());
if (!nameLength)
return false;
- info.name = String(name.get(), nameLength);
+
+ String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, String(name.get(), nameLength));
+
+ info.name = originalName;
info.type = type;
info.size = size;
return true;
@@ -659,11 +656,12 @@ bool GraphicsContext3D::getActiveUniform(Platform3DObject program, GC3Duint inde
::glGetActiveUniform(program, index, maxUniformSize, &nameLength, &size, &type, name.get());
if (!nameLength)
return false;
-
- info.name = String(name.get(), nameLength);
+
+ String originalName = originalSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, String(name.get(), nameLength));
+
+ info.name = originalName;
info.type = type;
info.size = size;
-
return true;
}
@@ -677,13 +675,59 @@ void GraphicsContext3D::getAttachedShaders(Platform3DObject program, GC3Dsizei m
::glGetAttachedShaders(program, maxCount, count, shaders);
}
+String GraphicsContext3D::mappedSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
+{
+ GC3Dsizei count;
+ Platform3DObject shaders[2];
+ getAttachedShaders(program, 2, &count, shaders);
+
+ for (GC3Dsizei i = 0; i < count; ++i) {
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
+ if (result == m_shaderSourceMap.end())
+ continue;
+
+ const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
+ ShaderSymbolMap::const_iterator symbolEntry = symbolMap.find(name);
+ if (symbolEntry != symbolMap.end())
+ return symbolEntry->value.mappedName;
+ }
+ return name;
+}
+
+String GraphicsContext3D::originalSymbolName(Platform3DObject program, ANGLEShaderSymbolType symbolType, const String& name)
+{
+ GC3Dsizei count;
+ Platform3DObject shaders[2];
+ getAttachedShaders(program, 2, &count, shaders);
+
+ for (GC3Dsizei i = 0; i < count; ++i) {
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shaders[i]);
+ if (result == m_shaderSourceMap.end())
+ continue;
+
+ const ShaderSymbolMap& symbolMap = result->value.symbolMap(symbolType);
+ ShaderSymbolMap::const_iterator symbolEntry;
+ for (symbolEntry = symbolMap.begin(); symbolEntry != symbolMap.end(); ++symbolEntry) {
+ if (symbolEntry->value.mappedName == name)
+ return symbolEntry->key;
+ }
+ }
+ return name;
+}
+
int GraphicsContext3D::getAttribLocation(Platform3DObject program, const String& name)
{
if (!program)
return -1;
makeContextCurrent();
- return ::glGetAttribLocation(program, name.utf8().data());
+
+ // The attribute name may have been translated during ANGLE compilation.
+ // Look through the corresponding ShaderSourceMap to make sure we
+ // reference the mapped name rather than the external name.
+ String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_ATTRIBUTE, name);
+
+ return ::glGetAttribLocation(program, mappedName.utf8().data());
}
GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes()
@@ -1132,7 +1176,7 @@ void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3
makeContextCurrent();
- HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
switch (pname) {
case DELETE_STATUS:
@@ -1144,7 +1188,7 @@ void GraphicsContext3D::getShaderiv(Platform3DObject shader, GC3Denum pname, GC3
*value = static_cast<int>(false);
return;
}
- *value = static_cast<int>(result->second.isValid);
+ *value = static_cast<int>(result->value.isValid);
break;
case INFO_LOG_LENGTH:
if (result == m_shaderSourceMap.end()) {
@@ -1167,11 +1211,11 @@ String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader)
makeContextCurrent();
- HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
if (result == m_shaderSourceMap.end())
return String();
- ShaderSourceEntry entry = result->second;
+ ShaderSourceEntry entry = result->value;
if (!entry.isValid)
return entry.log;
@@ -1193,11 +1237,11 @@ String GraphicsContext3D::getShaderSource(Platform3DObject shader)
makeContextCurrent();
- HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+ ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
if (result == m_shaderSourceMap.end())
return String();
- return result->second.source;
+ return result->value.source;
}
@@ -1230,7 +1274,13 @@ GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const St
ASSERT(program);
makeContextCurrent();
- return ::glGetUniformLocation(program, name.utf8().data());
+
+ // The uniform name may have been translated during ANGLE compilation.
+ // Look through the corresponding ShaderSourceMap to make sure we
+ // reference the mapped name rather than the external name.
+ String mappedName = mappedSymbolName(program, SHADER_SYMBOL_TYPE_UNIFORM, name);
+
+ return ::glGetUniformLocation(program, mappedName.utf8().data());
}
void GraphicsContext3D::getVertexAttribfv(GC3Duint index, GC3Denum pname, GC3Dfloat* value)
diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
index 4d1530c4b..991571d42 100644
--- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
+++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp
@@ -39,7 +39,6 @@
#include "LayerWebKitThread.h"
#endif
#include "NotImplemented.h"
-#include "OpenGLESShims.h"
namespace WebCore {
@@ -66,14 +65,14 @@ void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsi
#else
if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) {
resolveMultisamplingIfNecessary(IntRect(x, y, width, height));
- ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
::glFlush();
}
::glReadPixels(x, y, width, height, format, type, data);
if (m_attrs.antialias && m_boundFBO == m_multisampleFBO)
- ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
#endif
}
@@ -122,12 +121,12 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
bool mustRestoreFBO = false;
if (m_boundFBO != m_fbo) {
mustRestoreFBO = true;
- ::glBindFramebufferEXT(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+ ::glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
}
::glBindTexture(GL_TEXTURE_2D, m_texture);
::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, pixelDataType, 0);
- ::glFramebufferTexture2DEXT(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
+ ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
::glBindTexture(GL_TEXTURE_2D, m_compositorTexture);
::glTexImage2D(GL_TEXTURE_2D, 0, m_internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0);
@@ -139,28 +138,28 @@ bool GraphicsContext3D::reshapeFBOs(const IntSize& size)
if (m_attrs.stencil || m_attrs.depth) {
// Use a 24 bit depth buffer where we know we have it.
if (supportPackedDepthStencilBuffer) {
- ::glBindTexture(GL_TEXTURE_2D, m_depthStencilBuffer);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GraphicsContext3D::DEPTH_STENCIL, width, height, 0, GraphicsContext3D::DEPTH_STENCIL, GraphicsContext3D::UNSIGNED_INT_24_8, 0);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
if (m_attrs.stencil)
- ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_depthStencilBuffer, 0);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
if (m_attrs.depth)
- ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthStencilBuffer, 0);
- ::glBindTexture(GL_TEXTURE_2D, 0);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, 0);
} else {
if (m_attrs.stencil) {
- ::glBindRenderbufferEXT(GraphicsContext3D::RENDERBUFFER, m_stencilBuffer);
- ::glRenderbufferStorageEXT(GraphicsContext3D::RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
- ::glFramebufferRenderbufferEXT(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_stencilBuffer);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_stencilBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencilBuffer);
}
if (m_attrs.depth) {
- ::glBindRenderbufferEXT(GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
- ::glRenderbufferStorageEXT(GraphicsContext3D::RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
- ::glFramebufferRenderbufferEXT(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_depthBuffer);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, m_depthBuffer);
+ ::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
+ ::glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthBuffer);
}
- ::glBindRenderbufferEXT(GraphicsContext3D::RENDERBUFFER, 0);
+ ::glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
}
- if (glCheckFramebufferStatusEXT(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
// FIXME: cleanup
notImplemented();
}
@@ -178,7 +177,7 @@ void GraphicsContext3D::resolveMultisamplingIfNecessary(const IntRect& rect)
void GraphicsContext3D::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
{
makeContextCurrent();
- ::glRenderbufferStorageEXT(target, internalformat, width, height);
+ ::glRenderbufferStorage(target, internalformat, width, height);
}
void GraphicsContext3D::getIntegerv(GC3Denum pname, GC3Dint* value)
@@ -238,11 +237,6 @@ Extensions3D* GraphicsContext3D::getExtensions()
return m_extensions.get();
}
-bool GraphicsContext3D::systemAllowsMultisamplingOnATICards() const
-{
- return false; // not applicable
-}
-
}
#endif // USE(3D_GRAPHICS)
diff --git a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp
index 584d78ff8..67013b1ac 100644
--- a/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp
+++ b/Source/WebCore/platform/graphics/opentype/OpenTypeVerticalData.cpp
@@ -256,6 +256,15 @@ struct FeatureList : TableBase {
return validateOffset<FeatureTable>(buffer, features[index].featureOffset);
return 0;
}
+
+ const FeatureTable* findFeature(OpenType::Tag tag, const SharedBuffer& buffer) const
+ {
+ for (uint16_t i = 0; i < featureCount; ++i) {
+ if (isValidEnd(buffer, &features[i]) && features[i].featureTag == tag)
+ return validateOffset<FeatureTable>(buffer, features[i].featureOffset);
+ }
+ return 0;
+ }
};
struct LangSysTable : TableBase {
@@ -361,9 +370,17 @@ struct GSUBTable : TableBase {
{
const LangSysTable* langSys = defaultLangSys(buffer);
const FeatureList* features = featureList(buffer);
- if (!langSys || !features)
+ if (!features)
return 0;
- return langSys->feature(featureTag, features, buffer);
+ const FeatureTable* feature = 0;
+ if (langSys)
+ feature = langSys->feature(featureTag, features, buffer);
+ if (!feature) {
+ // If the font has no langSys table, or has no default script and the first script doesn't
+ // have the requested feature, then use the first matching feature directly.
+ feature = features->findFeature(featureTag, buffer);
+ }
+ return feature;
}
bool getVerticalGlyphSubstitutions(HashMap<Glyph, Glyph>* map, const SharedBuffer& buffer) const
diff --git a/Source/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp
index d681d7581..1a68aeff8 100644
--- a/Source/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp
+++ b/Source/WebCore/platform/graphics/openvg/EGLDisplayOpenVG.cpp
@@ -121,7 +121,7 @@ EGLDisplayOpenVG::~EGLDisplayOpenVG()
HashMap<EGLSurface, EGLint>::const_iterator end = m_surfaceConfigIds.end();
for (HashMap<EGLSurface, EGLint>::const_iterator it = m_surfaceConfigIds.begin(); it != end; ++it)
- destroySurface((*it).first);
+ destroySurface((*it).key);
eglTerminate(m_display);
ASSERT_EGL_NO_ERROR();
@@ -338,7 +338,7 @@ void EGLDisplayOpenVG::destroySurface(const EGLSurface& surface)
// ...but only if there's no other surfaces associated to that context.
for (HashMap<EGLSurface, EGLint>::iterator it = m_surfaceConfigIds.begin(); it != end; ++it) {
- if ((*it).second == surfaceConfigId) {
+ if ((*it).value == surfaceConfigId) {
isContextReferenced = true;
break;
}
@@ -354,7 +354,7 @@ void EGLDisplayOpenVG::destroySurface(const EGLSurface& surface)
HashMap<EGLNativeWindowType, EGLSurface>::iterator end = m_windowSurfaces.end();
for (HashMap<EGLNativeWindowType, EGLSurface>::iterator it = m_windowSurfaces.begin(); it != end; ++it) {
- if ((*it).second == surface) {
+ if ((*it).value == surface) {
m_windowSurfaces.remove(it);
break;
}
@@ -409,7 +409,7 @@ EGLContext EGLDisplayOpenVG::contextForSurface(const EGLSurface& surface)
HashMap<EGLint, EGLContext>::iterator end = m_contexts.end();
for (HashMap<EGLint, EGLContext>::iterator it = m_contexts.begin(); it != end; ++it) {
- eglMakeCurrent(m_display, surface, surface, (*it).second);
+ eglMakeCurrent(m_display, surface, surface, (*it).value);
if (eglGetError() == EGL_SUCCESS) {
// Restore previous surface/context.
if (currentContext != EGL_NO_CONTEXT) {
@@ -417,8 +417,8 @@ EGLContext EGLDisplayOpenVG::contextForSurface(const EGLSurface& surface)
ASSERT_EGL_NO_ERROR();
}
// Cool, surface is compatible to one of our existing contexts.
- m_compatibleConfigIds.set(surfaceConfigId, (*it).first);
- return (*it).second;
+ m_compatibleConfigIds.set(surfaceConfigId, (*it).key);
+ return (*it).value;
}
}
// Restore previous surface/context.
diff --git a/Source/WebCore/platform/graphics/pango/FontCachePango.cpp b/Source/WebCore/platform/graphics/pango/FontCachePango.cpp
index 2b12c3553..06d63c50f 100644
--- a/Source/WebCore/platform/graphics/pango/FontCachePango.cpp
+++ b/Source/WebCore/platform/graphics/pango/FontCachePango.cpp
@@ -35,17 +35,17 @@ void FontCache::platformInit()
ASSERT_NOT_REACHED();
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
return 0;
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
// FIXME: Would be even better to somehow get the user's default font here.
// For now we'll pick the default that the user would get without changing any prefs.
diff --git a/Source/WebCore/platform/graphics/pango/FontPango.cpp b/Source/WebCore/platform/graphics/pango/FontPango.cpp
index 03507c4c7..b91bfc980 100644
--- a/Source/WebCore/platform/graphics/pango/FontPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/FontPango.cpp
@@ -371,7 +371,7 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
{
#if USE(FREETYPE)
if (!primaryFont()->platformData().m_pattern)
- return floatWidthForSimpleText(run, 0, fallbackFonts, overflow);
+ return floatWidthForSimpleText(run, fallbackFonts, overflow);
#endif
if (!run.length())
diff --git a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
index ee8ee0f74..4fc1fbe3e 100644
--- a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
@@ -84,32 +84,32 @@ void SimpleFontData::platformDestroy()
{
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
FontDescription desc = FontDescription(fontDescription);
desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
FontPlatformData platformData(desc, desc.family().family());
- return adoptPtr(new SimpleFontData(platformData));
+ return SimpleFontData::create(platformData);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/Source/WebCore/platform/graphics/qt/FontCacheQt.cpp b/Source/WebCore/platform/graphics/qt/FontCacheQt.cpp
index b58198fa3..6d1ee72f2 100644
--- a/Source/WebCore/platform/graphics/qt/FontCacheQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/FontCacheQt.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "FontCache.h"
+#include "Font.h"
#include "FontDescription.h"
#include "FontPlatformData.h"
-#include "Font.h"
#include <utility>
#include <wtf/ListHashSet.h>
#include <wtf/StdLibExtras.h>
@@ -63,7 +63,7 @@ static QRawFont rawFontForCharacters(const QString& string, const QRawFont& font
return glyphs.rawFont();
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
QString qstring = QString::fromRawData(reinterpret_cast<const QChar*>(characters), length);
QRawFont computedFont = rawFontForCharacters(qstring, font.rawFont());
@@ -73,12 +73,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
return getCachedFontData(&alternateFont, DoNotRetain);
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
const AtomicString fallbackFamily = QFont(fontDescription.family().family()).lastResortFamily();
return getCachedFontData(new FontPlatformData(fontDescription, fallbackFamily), shouldRetain);
diff --git a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
index fbf9a158d..8d4efeca2 100644
--- a/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
+++ b/Source/WebCore/platform/graphics/qt/FontCustomPlatformData.h
@@ -26,10 +26,10 @@
#include "FontRenderingMode.h"
#include "FontWidthVariant.h"
#include "TextOrientation.h"
+#include <QRawFont>
#include <wtf/FastAllocBase.h>
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
-#include <QRawFont>
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 1678c49fa..69aa86591 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -69,7 +69,7 @@ public:
#endif
#if USE(GRAPHICS_SURFACE)
virtual uint32_t copyToGraphicsSurface();
- virtual uint64_t graphicsSurfaceToken() const;
+ virtual GraphicsSurfaceToken graphicsSurfaceToken() const;
#endif
QRectF boundingRect() const;
@@ -100,13 +100,6 @@ bool GraphicsContext3D::isGLES2Compliant() const
#endif
}
-#if !USE(OPENGL_ES_2)
-void GraphicsContext3D::releaseShaderCompiler()
-{
- notImplemented();
-}
-#endif
-
GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle)
: m_context(context)
, m_hostWindow(hostWindow)
@@ -206,6 +199,11 @@ void GraphicsContext3DPrivate::initializeANGLE()
// Always set to 1 for OpenGL ES.
ANGLEResources.MaxDrawBuffers = 1;
+
+ Extensions3D* extensions = m_context->getExtensions();
+ if (extensions->supports("GL_ARB_texture_rectangle"))
+ ANGLEResources.ARB_texture_rectangle = 1;
+
m_context->m_compiler.setResources(ANGLEResources);
}
@@ -291,7 +289,7 @@ uint32_t GraphicsContext3DPrivate::copyToGraphicsSurface()
return frontBuffer;
}
-uint64_t GraphicsContext3DPrivate::graphicsSurfaceToken() const
+GraphicsSurfaceToken GraphicsContext3DPrivate::graphicsSurfaceToken() const
{
return m_graphicsSurface->exportToken();
}
@@ -492,16 +490,18 @@ bool GraphicsContext3D::getImageData(Image* image,
if (!image)
return false;
- QImage nativeImage;
+ QImage qtImage;
// Is image already loaded? If not, load it.
if (image->data())
- nativeImage = QImage::fromData(reinterpret_cast<const uchar*>(image->data()->data()), image->data()->size());
- else
- nativeImage = *image->nativeImageForCurrentFrame();
-
+ qtImage = QImage::fromData(reinterpret_cast<const uchar*>(image->data()->data()), image->data()->size());
+ else {
+ QPixmap* nativePixmap = image->nativeImageForCurrentFrame();
+ // With QPA, we can avoid a deep copy.
+ qtImage = *nativePixmap->handle()->buffer();
+ }
AlphaOp alphaOp = AlphaDoNothing;
- switch (nativeImage.format()) {
+ switch (qtImage.format()) {
case QImage::Format_RGB32:
// For opaque images, we should not premultiply or unmultiply alpha.
break;
@@ -515,7 +515,7 @@ bool GraphicsContext3D::getImageData(Image* image,
break;
default:
// The image has a format that is not supported in packPixels. We have to convert it here.
- nativeImage = nativeImage.convertToFormat(premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32);
+ qtImage = qtImage.convertToFormat(premultiplyAlpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_ARGB32);
break;
}
@@ -526,7 +526,7 @@ bool GraphicsContext3D::getImageData(Image* image,
outputVector.resize(packedSize);
- return packPixels(nativeImage.constBits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, alphaOp, outputVector.data());
+ return packPixels(qtImage.constBits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, alphaOp, outputVector.data());
}
void GraphicsContext3D::setContextLostCallback(PassOwnPtr<ContextLostCallback>)
diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 5c8a3ae24..c2ab6dfb0 100644
--- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -283,12 +283,13 @@ GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p, cons
GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
{
+ delete shadow;
+
if (!platformContextIsOwned)
return;
QPaintDevice* device = painter->device();
painter->end();
- delete shadow;
delete painter;
delete device;
}
@@ -1066,7 +1067,7 @@ void GraphicsContext::clearPlatformShadow()
m_data->shadow->clear();
}
-void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QImage& alphaMask)
+void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask)
{
QPainter* p = m_data->p();
@@ -1101,7 +1102,7 @@ void GraphicsContext::beginPlatformTransparencyLayer(float opacity)
h = int(qBound(qreal(0), deviceClip.height(), (qreal)h) + 2);
}
- QImage emptyAlphaMask;
+ QPixmap emptyAlphaMask;
m_data->layers.push(new TransparencyLayer(p, QRect(x, y, w, h), opacity, emptyAlphaMask));
++m_data->layerCount;
}
@@ -1115,7 +1116,7 @@ void GraphicsContext::endPlatformTransparencyLayer()
if (!layer->alphaMask.isNull()) {
layer->painter.resetTransform();
layer->painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- layer->painter.drawImage(QPoint(), layer->alphaMask);
+ layer->painter.drawPixmap(QPoint(), layer->alphaMask);
} else
--m_data->layerCount; // see the comment for layerCount
layer->painter.end();
@@ -1124,7 +1125,7 @@ void GraphicsContext::endPlatformTransparencyLayer()
p->save();
p->resetTransform();
p->setOpacity(layer->opacity);
- p->drawImage(layer->offset, layer->image);
+ p->drawPixmap(layer->offset, layer->pixmap);
p->restore();
delete layer;
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
index 94065d3a6..9cf782bea 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferDataQt.h
@@ -25,8 +25,8 @@
#include "Image.h"
-#include <QImage>
#include <QPainter>
+#include <QPixmap>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
@@ -39,7 +39,9 @@ class ImageBufferData {
public:
ImageBufferData(const IntSize&);
- QImage m_nativeImage;
+ QImage toQImage() const;
+
+ QPixmap m_pixmap;
OwnPtr<QPainter> m_painter;
RefPtr<Image> m_image;
};
diff --git a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index 32dd39a5f..ac27dc25a 100644
--- a/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -32,7 +32,6 @@
#include "GraphicsContext.h"
#include "ImageData.h"
#include "MIMETypeRegistry.h"
-#include "NativeImageQt.h"
#include "StillImageQt.h"
#include "TransparencyLayer.h"
#include <wtf/text/CString.h>
@@ -43,22 +42,23 @@
#include <QImage>
#include <QImageWriter>
#include <QPainter>
+#include <QPixmap>
#include <math.h>
namespace WebCore {
ImageBufferData::ImageBufferData(const IntSize& size)
- : m_nativeImage(size, NativeImageQt::defaultFormatForAlphaEnabledImages())
+ : m_pixmap(size)
{
- if (m_nativeImage.isNull())
+ if (m_pixmap.isNull())
return;
- m_nativeImage.fill(QColor(Qt::transparent));
+ m_pixmap.fill(QColor(Qt::transparent));
QPainter* painter = new QPainter;
m_painter = adoptPtr(painter);
- if (!painter->begin(&m_nativeImage))
+ if (!painter->begin(&m_pixmap))
return;
// Since ImageBuffer is used mainly for Canvas, explicitly initialize
@@ -76,7 +76,22 @@ ImageBufferData::ImageBufferData(const IntSize& size)
painter->setBrush(brush);
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
- m_image = StillImage::createForRendering(&m_nativeImage);
+ m_image = StillImage::createForRendering(&m_pixmap);
+}
+
+QImage ImageBufferData::toQImage() const
+{
+ QPaintEngine* paintEngine = m_pixmap.paintEngine();
+ if (!paintEngine || paintEngine->type() != QPaintEngine::Raster)
+ return m_pixmap.toImage();
+
+ // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it.
+ // For performance reasons, we don't want that here, so we temporarily redirect the paint engine.
+ QPaintDevice* currentPaintDevice = paintEngine->paintDevice();
+ paintEngine->setPaintDevice(0);
+ QImage image = m_pixmap.toImage();
+ paintEngine->setPaintDevice(currentPaintDevice);
+ return image;
}
ImageBuffer::ImageBuffer(const IntSize& size, float /* resolutionScale */, ColorSpace, RenderingMode, DeferralMode, bool& success)
@@ -105,9 +120,9 @@ GraphicsContext* ImageBuffer::context() const
PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const
{
if (copyBehavior == CopyBackingStore)
- return StillImage::create(m_data.m_nativeImage);
+ return StillImage::create(m_data.m_pixmap);
- return StillImage::createForRendering(&m_data.m_nativeImage);
+ return StillImage::createForRendering(&m_data.m_pixmap);
}
void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
@@ -134,12 +149,12 @@ void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& src
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& floatRect) const
{
- QImage* nativeImage = m_data.m_image->nativeImageForCurrentFrame();
+ QPixmap* nativeImage = m_data.m_image->nativeImageForCurrentFrame();
if (!nativeImage)
return;
IntRect rect = enclosingIntRect(floatRect);
- QImage alphaMask = *nativeImage;
+ QPixmap alphaMask = *nativeImage;
context->pushTransparencyLayerInternal(rect, 1.0, alphaMask);
}
@@ -150,7 +165,7 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
if (isPainting)
m_data.m_painter->end();
- QImage image = m_data.m_nativeImage.convertToFormat(QImage::Format_ARGB32);
+ QImage image = m_data.toQImage().convertToFormat(QImage::Format_ARGB32);
ASSERT(!image.isNull());
uchar* bits = image.bits();
@@ -167,10 +182,20 @@ void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
}
}
- m_data.m_nativeImage = image;
+ m_data.m_pixmap = QPixmap::fromImage(image);
if (isPainting)
- m_data.m_painter->begin(&m_data.m_nativeImage);
+ m_data.m_painter->begin(&m_data.m_pixmap);
+}
+
+static inline quint32 convertABGRToARGB(quint32 pixel)
+{
+ return ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+}
+
+static inline quint32 convertARGBToABGR(quint32 pixel)
+{
+ return convertABGRToARGB(pixel);
}
template <Multiply multiplied>
@@ -209,7 +234,7 @@ PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const ImageBuffe
int numRows = endy - originy;
// NOTE: For unmultiplied data, we undo the premultiplication below.
- QImage image = imageData.m_nativeImage.convertToFormat(NativeImageQt::defaultFormatForAlphaEnabledImages());
+ QImage image = imageData.toQImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
ASSERT(!image.isNull());
@@ -217,40 +242,18 @@ PassRefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const ImageBuffe
const uchar* bits = image.constBits();
quint32* destRows = reinterpret_cast_ptr<quint32*>(&data[desty * rect.width() * 4 + destx * 4]);
-
- if (multiplied == Unmultiplied) {
- for (int y = 0; y < numRows; ++y) {
- const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- QRgb pixel = scanLine[x + originx];
- int alpha = qAlpha(pixel);
- // Un-premultiply and convert RGB to BGR.
- if (alpha == 255)
- destRows[x] = (0xFF000000
- | (qBlue(pixel) << 16)
- | (qGreen(pixel) << 8)
- | (qRed(pixel)));
- else if (alpha > 0)
- destRows[x] = ((alpha << 24)
- | (((255 * qBlue(pixel)) / alpha)) << 16)
- | (((255 * qGreen(pixel)) / alpha) << 8)
- | ((255 * qRed(pixel)) / alpha);
- else
- destRows[x] = 0;
- }
- destRows += rect.width();
- }
- } else {
- for (int y = 0; y < numRows; ++y) {
- const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- QRgb pixel = scanLine[x + originx];
- // Convert RGB to BGR.
- destRows[x] = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
-
- }
- destRows += rect.width();
+ for (int y = 0; y < numRows; ++y) {
+ const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
+ for (int x = 0; x < numColumns; x++) {
+ QRgb pixel = scanLine[x + originx];
+ Color pixelColor;
+ if (multiplied == Unmultiplied)
+ pixelColor = colorFromPremultipliedARGB(Color(qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel)).rgb());
+ else
+ pixelColor = Color(qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel));
+ destRows[x] = convertARGBToABGR(pixelColor.rgb());
}
+ destRows += rect.width();
}
return result.release();
@@ -266,22 +269,6 @@ PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRe
return getImageData<Premultiplied>(rect, m_data, m_size);
}
-static inline unsigned int premultiplyABGRtoARGB(unsigned int x)
-{
- unsigned int a = x >> 24;
- if (a == 255)
- return (x << 16) | ((x >> 16) & 0xff) | (x & 0xff00ff00);
- unsigned int t = (x & 0xff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t = ((t << 16) | (t >> 16)) & 0xff00ff;
-
- x = ((x >> 8) & 0xff) * a;
- x = (x + ((x >> 8) & 0xff) + 0x80);
- x &= 0xff00;
- x |= t | (a << 24);
- return x;
-}
-
void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem)
{
ASSERT(sourceRect.width() > 0);
@@ -319,31 +306,21 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
const quint32* srcScanLine = reinterpret_cast_ptr<const quint32*>(source->data() + originy * srcBytesPerRow + originx * 4);
- if (multiplied == Unmultiplied) {
- for (int y = 0; y < numRows; ++y) {
- quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- // Premultiply and convert BGR to RGB.
- quint32 pixel = srcScanLine[x];
- destScanLine[x] = premultiplyABGRtoARGB(pixel);
- }
- srcScanLine += sourceSize.width();
- }
- } else {
- for (int y = 0; y < numRows; ++y) {
- quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- // Convert BGR to RGB.
- quint32 pixel = srcScanLine[x];
- destScanLine[x] = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
- }
- srcScanLine += sourceSize.width();
+ for (int y = 0; y < numRows; ++y) {
+ quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
+ for (int x = 0; x < numColumns; x++) {
+ quint32 pixel = convertABGRToARGB(srcScanLine[x]);
+ if (multiplied == Unmultiplied)
+ destScanLine[x] = premultipliedARGBFromColor(Color(pixel));
+ else
+ destScanLine[x] = pixel;
}
+ srcScanLine += sourceSize.width();
}
bool isPainting = m_data.m_painter->isActive();
if (!isPainting)
- m_data.m_painter->begin(&m_data.m_nativeImage);
+ m_data.m_painter->begin(&m_data.m_pixmap);
else {
m_data.m_painter->save();
@@ -362,7 +339,7 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
m_data.m_painter->restore();
}
-static bool encodeImage(const QImage& image, const String& format, const double* quality, QByteArray& data)
+static bool encodeImage(const QPixmap& pixmap, const String& format, const double* quality, QByteArray& data)
{
int compressionQuality = 100;
if (quality && *quality >= 0.0 && *quality <= 1.0)
@@ -370,7 +347,7 @@ static bool encodeImage(const QImage& image, const String& format, const double*
QBuffer buffer(&data);
buffer.open(QBuffer::WriteOnly);
- bool success = image.save(&buffer, format.utf8().data(), compressionQuality);
+ bool success = pixmap.save(&buffer, format.utf8().data(), compressionQuality);
buffer.close();
return success;
@@ -382,10 +359,10 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo
// QImageWriter does not support mimetypes. It does support Qt image formats (png,
// gif, jpeg..., xpm) so skip the image/ to get the Qt image format used to encode
- // the m_nativeImage image.
+ // the m_pixmap image.
QByteArray data;
- if (!encodeImage(m_data.m_nativeImage, mimeType.substring(sizeof "image"), quality, data))
+ if (!encodeImage(m_data.m_pixmap, mimeType.substring(sizeof "image"), quality, data))
return "data:,";
return "data:" + mimeType + ";base64," + data.toBase64().data();
diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index f039e4300..a7d9f7523 100644
--- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "ImageDecoderQt.h"
-#include <QtCore/QByteArray>
#include <QtCore/QBuffer>
+#include <QtCore/QByteArray>
#include <QtGui/QImageReader>
namespace WebCore {
@@ -272,7 +272,9 @@ NativeImagePtr ImageFrame::asNewNativeImage() const
else
format = QImage::Format_RGB32;
- return new QImage(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), format);
+ QImage img(reinterpret_cast<uchar*>(m_bytes), m_size.width(), m_size.height(), sizeof(PixelData) * m_size.width(), format);
+
+ return new QPixmap(QPixmap::fromImage(img));
}
}
diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h
index 3e421c336..8ae3b4239 100644
--- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -28,11 +28,11 @@
#define ImageDecoderQt_h
#include "ImageDecoder.h"
+#include <QtCore/QBuffer>
+#include <QtCore/QHash>
+#include <QtCore/QList>
#include <QtGui/QImageReader>
#include <QtGui/QPixmap>
-#include <QtCore/QList>
-#include <QtCore/QHash>
-#include <QtCore/QBuffer>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp
index 5be31cea0..fc01c407d 100644
--- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -37,7 +37,6 @@
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageObserver.h"
-#include "NativeImageQt.h"
#include "ShadowBlur.h"
#include "StillImageQt.h"
#include <wtf/text/WTFString.h>
@@ -56,7 +55,7 @@
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP, int hbitmapFormat = 0);
#endif
-typedef QHash<QByteArray, QImage> WebGraphicHash;
+typedef QHash<QByteArray, QPixmap> WebGraphicHash;
Q_GLOBAL_STATIC(WebGraphicHash, _graphics)
static void earlyClearGraphics()
@@ -70,28 +69,28 @@ static WebGraphicHash* graphics()
if (hash->isEmpty()) {
- // prevent ~QImage running after ~QApplication (leaks native images)
+ // prevent ~QPixmap running after ~QApplication (leaks native pixmaps)
qAddPostRoutine(earlyClearGraphics);
// QWebSettings::MissingImageGraphic
- hash->insert("missingImage", QImage(QLatin1String(":webkit/resources/missingImage.png")));
+ hash->insert("missingImage", QPixmap(QLatin1String(":webkit/resources/missingImage.png")));
// QWebSettings::MissingPluginGraphic
- hash->insert("nullPlugin", QImage(QLatin1String(":webkit/resources/nullPlugin.png")));
+ hash->insert("nullPlugin", QPixmap(QLatin1String(":webkit/resources/nullPlugin.png")));
// QWebSettings::DefaultFrameIconGraphic
- hash->insert("urlIcon", QImage(QLatin1String(":webkit/resources/urlIcon.png")));
+ hash->insert("urlIcon", QPixmap(QLatin1String(":webkit/resources/urlIcon.png")));
// QWebSettings::TextAreaSizeGripCornerGraphic
- hash->insert("textAreaResizeCorner", QImage(QLatin1String(":webkit/resources/textAreaResizeCorner.png")));
+ hash->insert("textAreaResizeCorner", QPixmap(QLatin1String(":webkit/resources/textAreaResizeCorner.png")));
// QWebSettings::DeleteButtonGraphic
- hash->insert("deleteButton", QImage(QLatin1String(":webkit/resources/deleteButton.png")));
+ hash->insert("deleteButton", QPixmap(QLatin1String(":webkit/resources/deleteButton.png")));
// QWebSettings::InputSpeechButtonGraphic
- hash->insert("inputSpeech", QImage(QLatin1String(":webkit/resources/inputSpeech.png")));
+ hash->insert("inputSpeech", QPixmap(QLatin1String(":webkit/resources/inputSpeech.png")));
}
return hash;
}
// This function loads resources into WebKit
-static QImage loadResourceImage(const char *name)
+static QPixmap loadResourcePixmap(const char *name)
{
return graphics()->value(name);
}
@@ -118,23 +117,23 @@ bool FrameData::clear(bool clearMetadata)
PassRefPtr<Image> Image::loadPlatformResource(const char* name)
{
- return StillImage::create(loadResourceImage(name));
+ return StillImage::create(loadResourcePixmap(name));
}
-void Image::setPlatformResource(const char* name, const QImage& image)
+void Image::setPlatformResource(const char* name, const QPixmap& pixmap)
{
WebGraphicHash* h = graphics();
- if (image.isNull())
+ if (pixmap.isNull())
h->remove(name);
else
- h->insert(name, image);
+ h->insert(name, pixmap);
}
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& destRect)
{
- QImage* frameImage = nativeImageForCurrentFrame();
- if (!frameImage) // If it's too early we won't have an image yet.
+ QPixmap* framePixmap = nativeImageForCurrentFrame();
+ if (!framePixmap) // If it's too early we won't have an image yet.
return;
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
@@ -149,38 +148,34 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
if (!dr.width() || !dr.height() || !tr.width() || !tr.height())
return;
- QImage image = *frameImage;
- if (tr.x() || tr.y() || tr.width() != image.width() || tr.height() != image.height())
- image = image.copy(tr);
+ QPixmap pixmap = *framePixmap;
+ if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height())
+ pixmap = pixmap.copy(tr);
CompositeOperator previousOperator = ctxt->compositeOperation();
- ctxt->setCompositeOperation(!image.hasAlphaChannel() && op == CompositeSourceOver ? CompositeCopy : op);
+ ctxt->setCompositeOperation(!pixmap.hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
QPainter* p = ctxt->platformContext();
QTransform transform(patternTransform);
- // If this would draw more than one scaled tile, we scale the image first and then use the result to draw.
+ // If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw.
if (transform.type() == QTransform::TxScale) {
QRectF tileRectInTargetCoords = (transform * QTransform().translate(phase.x(), phase.y())).mapRect(tr);
bool tileWillBePaintedOnlyOnce = tileRectInTargetCoords.contains(dr);
if (!tileWillBePaintedOnlyOnce) {
- QSizeF scaledSize(float(image.width()) * transform.m11(), float(image.height()) * transform.m22());
- QImage scaledImage;
- if (image.hasAlphaChannel()) {
- scaledImage = QImage(scaledSize.toSize(), NativeImageQt::defaultFormatForAlphaEnabledImages());
- scaledImage.fill(Qt::transparent);
- } else
- scaledImage = QImage(scaledSize.toSize(), NativeImageQt::defaultFormatForOpaqueImages());
-
+ QSizeF scaledSize(float(pixmap.width()) * transform.m11(), float(pixmap.height()) * transform.m22());
+ QPixmap scaledPixmap(scaledSize.toSize());
+ if (pixmap.hasAlpha())
+ scaledPixmap.fill(Qt::transparent);
{
- QPainter painter(&scaledImage);
+ QPainter painter(&scaledPixmap);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setRenderHints(p->renderHints());
- painter.drawImage(QRect(0, 0, scaledImage.width(), scaledImage.height()), image);
+ painter.drawPixmap(QRect(0, 0, scaledPixmap.width(), scaledPixmap.height()), pixmap);
}
- image = scaledImage;
+ pixmap = scaledPixmap;
transform = QTransform::fromTranslate(transform.dx(), transform.dy());
}
}
@@ -189,7 +184,7 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
transform *= QTransform().translate(phase.x(), phase.y());
transform.translate(tr.x(), tr.y());
- QBrush b(image);
+ QBrush b(pixmap);
b.setTransform(transform);
p->fillRect(dr, b);
@@ -199,7 +194,7 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const
imageObserver()->didDraw(this);
}
-BitmapImage::BitmapImage(QImage* image, ImageObserver* observer)
+BitmapImage::BitmapImage(QPixmap* pixmap, ImageObserver* observer)
: Image(observer)
, m_currentFrame(0)
, m_frames(0)
@@ -217,14 +212,14 @@ BitmapImage::BitmapImage(QImage* image, ImageObserver* observer)
, m_sizeAvailable(true)
, m_haveFrameCount(true)
{
- int width = image->width();
- int height = image->height();
+ int width = pixmap->width();
+ int height = pixmap->height();
m_decodedSize = width * height * 4;
m_size = IntSize(width, height);
m_frames.grow(1);
- m_frames[0].m_frame = image;
- m_frames[0].m_hasAlpha = image->hasAlphaChannel();
+ m_frames[0].m_frame = pixmap;
+ m_frames[0].m_hasAlpha = pixmap->hasAlpha();
m_frames[0].m_haveMetadata = true;
checkForSolidColor();
}
@@ -245,8 +240,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
if (normalizedSrc.isEmpty() || normalizedDst.isEmpty())
return;
- QImage* image = nativeImageForCurrentFrame();
-
+ QPixmap* image = nativeImageForCurrentFrame();
if (!image)
return;
@@ -260,19 +254,19 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
#endif
CompositeOperator previousOperator = ctxt->compositeOperation();
- ctxt->setCompositeOperation(!image->hasAlphaChannel() && op == CompositeSourceOver ? CompositeCopy : op);
+ ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
if (ctxt->hasShadow()) {
ShadowBlur* shadow = ctxt->shadowBlur();
GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
if (shadowContext) {
QPainter* shadowPainter = shadowContext->platformContext();
- shadowPainter->drawImage(normalizedDst, *image, normalizedSrc);
+ shadowPainter->drawPixmap(normalizedDst, *image, normalizedSrc);
shadow->endShadowLayer(ctxt);
}
}
- ctxt->platformContext()->drawImage(normalizedDst, *image, normalizedSrc);
+ ctxt->platformContext()->drawPixmap(normalizedDst, *image, normalizedSrc);
ctxt->setCompositeOperation(previousOperator);
@@ -288,20 +282,20 @@ void BitmapImage::checkForSolidColor()
if (frameCount() > 1)
return;
- QImage* frameImage = frameAtIndex(0);
- if (!frameImage || frameImage->width() != 1 || frameImage->height() != 1)
+ QPixmap* framePixmap = frameAtIndex(0);
+ if (!framePixmap || framePixmap->width() != 1 || framePixmap->height() != 1)
return;
m_isSolidColor = true;
- m_solidColor = QColor::fromRgba(frameImage->pixel(0, 0));
+ m_solidColor = QColor::fromRgba(framePixmap->toImage().pixel(0, 0));
}
#if OS(WINDOWS)
PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap)
{
- QImage* nativeImage = new QImage(qt_pixmapFromWinHBITMAP(hBitmap).toImage());
+ QPixmap* qPixmap = new QPixmap(qt_pixmapFromWinHBITMAP(hBitmap));
- return BitmapImage::create(nativeImage);
+ return BitmapImage::create(qPixmap);
}
#endif
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 5ad418c23..9ec765caa 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -31,20 +31,16 @@
#include "RenderVideo.h"
#include "TimeRanges.h"
#include "Widget.h"
-#include "qwebframe.h"
-#include "qwebpage.h"
-#include <QGraphicsScene>
-#include <QGraphicsVideoItem>
#include <QMediaPlayerControl>
#include <QMediaService>
#include <QNetworkAccessManager>
+#include <QNetworkCookie>
#include <QNetworkCookieJar>
#include <QNetworkRequest>
#include <QPainter>
#include <QPoint>
#include <QRect>
-#include <QStyleOptionGraphicsItem>
#include <QTime>
#include <QTimer>
#include <QUrl>
@@ -96,7 +92,7 @@ MediaPlayer::SupportsType MediaPlayerPrivateQt::supportsType(const String& mime,
codecListTrimmed.append(codecStrTrimmed);
}
- if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QtMultimediaKit::ProbablySupported)
+ if (QMediaPlayer::hasSupport(mime, codecListTrimmed) >= QtMultimedia::ProbablySupported)
return MediaPlayer::IsSupported;
return MediaPlayer::MayBeSupported;
@@ -106,21 +102,17 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player)
: m_webCorePlayer(player)
, m_mediaPlayer(new QMediaPlayer)
, m_mediaPlayerControl(0)
- , m_videoItem(new QGraphicsVideoItem)
- , m_videoScene(new QGraphicsScene)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
, m_currentSize(0, 0)
, m_naturalSize(RenderVideo::defaultSize())
- , m_isVisible(false)
, m_isSeeking(false)
, m_composited(false)
, m_preload(MediaPlayer::Auto)
, m_bytesLoadedAtLastDidLoadingProgress(0)
, m_suppressNextPlaybackChanged(false)
{
- m_mediaPlayer->setVideoOutput(m_videoItem);
- m_videoScene->addItem(m_videoItem);
+ m_mediaPlayer->setVideoOutput(this);
// Signal Handlers
connect(m_mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
@@ -139,10 +131,8 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player)
this, SLOT(volumeChanged(int)));
connect(m_mediaPlayer, SIGNAL(mutedChanged(bool)),
this, SLOT(mutedChanged(bool)));
- connect(m_videoScene, SIGNAL(changed(QList<QRectF>)),
- this, SLOT(repaint()));
- connect(m_videoItem, SIGNAL(nativeSizeChanged(QSizeF)),
- this, SLOT(nativeSizeChanged(QSizeF)));
+ connect(this, SIGNAL(surfaceFormatChanged(const QVideoSurfaceFormat&)),
+ this, SLOT(surfaceFormatChanged(const QVideoSurfaceFormat&)));
// Grab the player control
if (QMediaService* service = m_mediaPlayer->service()) {
@@ -158,7 +148,6 @@ MediaPlayerPrivateQt::~MediaPlayerPrivateQt()
m_mediaPlayer->setMedia(QMediaContent());
delete m_mediaPlayer;
- delete m_videoScene;
}
bool MediaPlayerPrivateQt::hasVideo() const
@@ -366,8 +355,8 @@ bool MediaPlayerPrivateQt::didLoadingProgress() const
{
unsigned bytesLoaded = 0;
QLatin1String bytesLoadedKey("bytes-loaded");
- if (m_mediaPlayer->availableExtendedMetaData().contains(bytesLoadedKey))
- bytesLoaded = m_mediaPlayer->extendedMetaData(bytesLoadedKey).toInt();
+ if (m_mediaPlayer->availableMetaData().contains(bytesLoadedKey))
+ bytesLoaded = m_mediaPlayer->metaData(bytesLoadedKey).toInt();
else
bytesLoaded = m_mediaPlayer->bufferStatus();
bool didLoadingProgress = bytesLoaded != m_bytesLoadedAtLastDidLoadingProgress;
@@ -377,8 +366,8 @@ bool MediaPlayerPrivateQt::didLoadingProgress() const
unsigned MediaPlayerPrivateQt::totalBytes() const
{
- if (m_mediaPlayer->availableMetaData().contains(QtMultimediaKit::Size))
- return m_mediaPlayer->metaData(QtMultimediaKit::Size).toInt();
+ if (m_mediaPlayer->availableMetaData().contains(QtMultimedia::MetaData::Size))
+ return m_mediaPlayer->metaData(QtMultimedia::MetaData::Size).toInt();
return 100;
}
@@ -420,9 +409,8 @@ MediaPlayer::ReadyState MediaPlayerPrivateQt::readyState() const
return m_readyState;
}
-void MediaPlayerPrivateQt::setVisible(bool visible)
+void MediaPlayerPrivateQt::setVisible(bool)
{
- m_isVisible = visible;
}
void MediaPlayerPrivateQt::mediaStatusChanged(QMediaPlayer::MediaStatus)
@@ -443,15 +431,20 @@ void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State)
m_suppressNextPlaybackChanged = false;
}
-void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF& size)
+void MediaPlayerPrivateQt::surfaceFormatChanged(const QVideoSurfaceFormat& format)
{
+ QSize size = format.sizeHint();
LOG(Media, "MediaPlayerPrivateQt::naturalSizeChanged(%dx%d)",
- size.toSize().width(), size.toSize().height());
+ size.width(), size.height());
if (!size.isValid())
return;
- m_naturalSize = size.toSize();
+ IntSize webCoreSize = size;
+ if (webCoreSize == m_naturalSize)
+ return;
+
+ m_naturalSize = webCoreSize;
m_webCorePlayer->sizeChanged();
}
@@ -544,7 +537,6 @@ void MediaPlayerPrivateQt::setSize(const IntSize& size)
return;
m_currentSize = size;
- m_videoItem->setSize(QSizeF(QSize(size)));
}
IntSize MediaPlayerPrivateQt::naturalSize() const
@@ -562,34 +554,58 @@ IntSize MediaPlayerPrivateQt::naturalSize() const
void MediaPlayerPrivateQt::removeVideoItem()
{
- m_oldNaturalSize = m_naturalSize;
- m_mediaPlayer->setVideoOutput(static_cast<QGraphicsVideoItem*>(0));
- m_videoScene->removeItem(m_videoItem);
+ m_mediaPlayer->setVideoOutput(static_cast<QAbstractVideoSurface*>(0));
}
void MediaPlayerPrivateQt::restoreVideoItem()
{
- m_mediaPlayer->setVideoOutput(m_videoItem);
- m_videoScene->addItem(m_videoItem);
- // FIXME: a qtmobility bug, need to reset the size when restore the videoitem, otherwise the size is 0
- // http://bugreports.qt.nokia.com/browse/QTMOBILITY-971
- nativeSizeChanged(QSize(m_oldNaturalSize));
+ m_mediaPlayer->setVideoOutput(this);
+}
+
+// Begin QAbstractVideoSurface implementation.
+
+bool MediaPlayerPrivateQt::start(const QVideoSurfaceFormat& format)
+{
+ m_currentVideoFrame = QVideoFrame();
+ m_frameFormat = format;
+
+ // If the pixel format is not supported by QImage, then we return false here and the QtMultimedia back-end
+ // will re-negotiate and call us again with a better format.
+ if (QVideoFrame::imageFormatFromPixelFormat(m_frameFormat.pixelFormat()) == QImage::Format_Invalid)
+ return false;
+
+ return QAbstractVideoSurface::start(format);
+}
+
+QList<QVideoFrame::PixelFormat> MediaPlayerPrivateQt::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
+{
+ QList<QVideoFrame::PixelFormat> formats;
+ switch (handleType) {
+ case QAbstractVideoBuffer::QPixmapHandle:
+ case QAbstractVideoBuffer::NoHandle:
+ formats << QVideoFrame::Format_RGB32 << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_RGB565;
+ break;
+ default: break;
+ }
+ return formats;
+}
+
+bool MediaPlayerPrivateQt::present(const QVideoFrame& frame)
+{
+ m_currentVideoFrame = frame;
+ m_webCorePlayer->repaint();
+ return true;
}
+// End QAbstractVideoSurface implementation.
+
void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_composited)
return;
#endif
- if (context->paintingDisabled())
- return;
-
- if (!m_isVisible)
- return;
-
- QPainter* painter = context->platformContext();
- m_videoScene->render(painter, QRectF(QRect(rect)), m_videoItem->sceneBoundingRect());
+ paintCurrentFrameInContext(context, rect);
}
void MediaPlayerPrivateQt::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
@@ -597,32 +613,38 @@ void MediaPlayerPrivateQt::paintCurrentFrameInContext(GraphicsContext* context,
if (context->paintingDisabled())
return;
- if (!m_isVisible)
+ if (!m_currentVideoFrame.isValid())
return;
- // Grab the painter and widget
QPainter* painter = context->platformContext();
- // Render the video, using the item as it might not be in the scene
- m_videoItem->paint(painter, 0, 0);
-}
-
-void MediaPlayerPrivateQt::repaint()
-{
- m_webCorePlayer->repaint();
+ if (m_currentVideoFrame.handleType() == QAbstractVideoBuffer::QPixmapHandle) {
+ painter->drawPixmap(rect, m_currentVideoFrame.handle().value<QPixmap>());
+ } else if (m_currentVideoFrame.map(QAbstractVideoBuffer::ReadOnly)) {
+ QImage image(m_currentVideoFrame.bits(),
+ m_frameFormat.frameSize().width(),
+ m_frameFormat.frameSize().height(),
+ m_currentVideoFrame.bytesPerLine(),
+ QVideoFrame::imageFormatFromPixelFormat(m_frameFormat.pixelFormat()));
+ const QRect target = rect;
+
+ if (m_frameFormat.scanLineDirection() == QVideoSurfaceFormat::BottomToTop) {
+ const QTransform oldTransform = painter->transform();
+ painter->scale(1, -1);
+ painter->translate(0, -target.bottom());
+ painter->drawImage(QRect(target.x(), 0, target.width(), target.height()), image);
+ painter->setTransform(oldTransform);
+ } else {
+ painter->drawImage(target, image);
+ }
+ m_currentVideoFrame.unmap();
+ }
}
#if USE(ACCELERATED_COMPOSITING)
-void MediaPlayerPrivateQt::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture*) const
-{
- GraphicsContext* context = textureMapper->graphicsContext();
- QPainter* painter = context->platformContext();
- painter->save();
- painter->setTransform(matrix);
- painter->setOpacity(opacity);
- m_videoScene->render(painter, QRectF(targetRect), m_videoItem->sceneBoundingRect());
- painter->restore();
+void MediaPlayerPrivateQt::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture*)
+{
}
#endif
diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
index f15af138d..8e31c9d6d 100644
--- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
+++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
@@ -22,8 +22,10 @@
#include "MediaPlayerPrivate.h"
+#include <QAbstractVideoSurface>
#include <QMediaPlayer>
#include <QObject>
+#include <QVideoSurfaceFormat>
QT_BEGIN_NAMESPACE
class QMediaPlayerControl;
@@ -37,9 +39,9 @@ QT_END_NAMESPACE
namespace WebCore {
-class MediaPlayerPrivateQt : public QObject, public MediaPlayerPrivateInterface
+class MediaPlayerPrivateQt : public QAbstractVideoSurface, public MediaPlayerPrivateInterface
#if USE(ACCELERATED_COMPOSITING)
- , public TextureMapperPlatformLayer
+ , public TextureMapperPlatformLayer
#endif
{
@@ -107,7 +109,7 @@ public:
virtual void acceleratedRenderingStateChanged() { }
// Const-casting here is safe, since all of TextureMapperPlatformLayer's functions are const.g
virtual PlatformLayer* platformLayer() const { return 0; }
- virtual void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask) const;
+ virtual void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask);
#endif
virtual PlatformMedia platformMedia() const;
@@ -116,17 +118,21 @@ public:
void removeVideoItem();
void restoreVideoItem();
+ // QAbstractVideoSurface methods
+ virtual bool start(const QVideoSurfaceFormat& format);
+ virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
+ virtual bool present(const QVideoFrame& frame);
+
private Q_SLOTS:
void mediaStatusChanged(QMediaPlayer::MediaStatus);
void handleError(QMediaPlayer::Error);
void stateChanged(QMediaPlayer::State);
- void nativeSizeChanged(const QSizeF&);
+ void surfaceFormatChanged(const QVideoSurfaceFormat&);
void positionChanged(qint64);
void durationChanged(qint64);
void bufferStatusChanged(int);
void volumeChanged(int);
void mutedChanged(bool);
- void repaint();
private:
void updateStates();
@@ -139,15 +145,14 @@ private:
MediaPlayer* m_webCorePlayer;
QMediaPlayer* m_mediaPlayer;
QMediaPlayerControl* m_mediaPlayerControl;
- QGraphicsVideoItem* m_videoItem;
- QGraphicsScene* m_videoScene;
+ QVideoSurfaceFormat m_frameFormat;
+ QVideoFrame m_currentVideoFrame;
mutable MediaPlayer::NetworkState m_networkState;
mutable MediaPlayer::ReadyState m_readyState;
IntSize m_currentSize;
IntSize m_naturalSize;
- IntSize m_oldNaturalSize;
bool m_isVisible;
bool m_isSeeking;
bool m_composited;
diff --git a/Source/WebCore/platform/graphics/qt/PathQt.cpp b/Source/WebCore/platform/graphics/qt/PathQt.cpp
index 4f65151b7..577023b46 100644
--- a/Source/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/PathQt.cpp
@@ -38,8 +38,8 @@
#include "NativeImageQt.h"
#include "StrokeStyleApplier.h"
#include <QPainterPath>
-#include <QTransform>
#include <QString>
+#include <QTransform>
#include <wtf/MathExtras.h>
#include <wtf/OwnPtr.h>
#include <wtf/text/WTFString.h>
@@ -149,11 +149,16 @@ void Path::translate(const FloatSize& size)
m_path.translate(size.width(), size.height());
}
-FloatRect Path::boundingRect() const
+FloatRect Path::fastBoundingRect() const
{
return m_path.controlPointRect();
}
+FloatRect Path::boundingRect() const
+{
+ return m_path.boundingRect();
+}
+
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) const
{
GraphicsContext* context = scratchContext();
diff --git a/Source/WebCore/platform/graphics/qt/PatternQt.cpp b/Source/WebCore/platform/graphics/qt/PatternQt.cpp
index 5c9412215..7aae62599 100644
--- a/Source/WebCore/platform/graphics/qt/PatternQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/PatternQt.cpp
@@ -33,12 +33,12 @@ namespace WebCore {
QBrush Pattern::createPlatformPattern() const
{
- QImage* image = tileImage()->nativeImageForCurrentFrame();
- if (!image)
+ QPixmap* pixmap = tileImage()->nativeImageForCurrentFrame();
+ if (!pixmap)
return QBrush();
// Qt merges patter space and user space itself
- QBrush brush(*image);
+ QBrush brush(*pixmap);
brush.setTransform(m_patternSpaceTransformation);
return brush;
diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 8ce9f77da..677d6086c 100644
--- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -61,30 +61,30 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return advances.at(0).x();
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
- return adoptPtr(new SimpleFontData(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false));
+ return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFraction);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFraction);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
diff --git a/Source/WebCore/platform/graphics/qt/StillImageQt.cpp b/Source/WebCore/platform/graphics/qt/StillImageQt.cpp
index 041252019..80666ba46 100644
--- a/Source/WebCore/platform/graphics/qt/StillImageQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/StillImageQt.cpp
@@ -36,41 +36,41 @@
namespace WebCore {
-StillImage::StillImage(const QImage& image)
- : m_image(new QImage(image))
- , m_ownsImage(true)
+StillImage::StillImage(const QPixmap& pixmap)
+ : m_pixmap(new QPixmap(pixmap))
+ , m_ownsPixmap(true)
{}
-StillImage::StillImage(const QImage* image)
- : m_image(image)
- , m_ownsImage(false)
+StillImage::StillImage(const QPixmap* pixmap)
+ : m_pixmap(pixmap)
+ , m_ownsPixmap(false)
{}
StillImage::~StillImage()
{
- if (m_ownsImage)
- delete m_image;
+ if (m_ownsPixmap)
+ delete m_pixmap;
}
bool StillImage::currentFrameHasAlpha()
{
- return m_image->hasAlphaChannel();
+ return m_pixmap->hasAlpha();
}
IntSize StillImage::size() const
{
- return IntSize(m_image->width(), m_image->height());
+ return IntSize(m_pixmap->width(), m_pixmap->height());
}
NativeImagePtr StillImage::nativeImageForCurrentFrame()
{
- return const_cast<NativeImagePtr>(m_image);
+ return const_cast<NativeImagePtr>(m_pixmap);
}
void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
const FloatRect& src, ColorSpace, CompositeOperator op)
{
- if (m_image->isNull())
+ if (m_pixmap->isNull())
return;
FloatRect normalizedSrc = src.normalized();
@@ -84,12 +84,12 @@ void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
if (shadowContext) {
QPainter* shadowPainter = shadowContext->platformContext();
- shadowPainter->drawImage(normalizedDst, *m_image, normalizedSrc);
+ shadowPainter->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc);
shadow->endShadowLayer(ctxt);
}
}
- ctxt->platformContext()->drawImage(normalizedDst, *m_image, normalizedSrc);
+ ctxt->platformContext()->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc);
ctxt->setCompositeOperation(previousOperator);
}
diff --git a/Source/WebCore/platform/graphics/qt/StillImageQt.h b/Source/WebCore/platform/graphics/qt/StillImageQt.h
index 8c9ec0d88..0609b5458 100644
--- a/Source/WebCore/platform/graphics/qt/StillImageQt.h
+++ b/Source/WebCore/platform/graphics/qt/StillImageQt.h
@@ -34,14 +34,14 @@ namespace WebCore {
class StillImage : public Image {
public:
- static PassRefPtr<StillImage> create(const QImage& image)
+ static PassRefPtr<StillImage> create(const QPixmap& pixmap)
{
- return adoptRef(new StillImage(image));
+ return adoptRef(new StillImage(pixmap));
}
- static PassRefPtr<StillImage> createForRendering(const QImage* image)
+ static PassRefPtr<StillImage> createForRendering(const QPixmap* pixmap)
{
- return adoptRef(new StillImage(image));
+ return adoptRef(new StillImage(pixmap));
}
virtual bool currentFrameHasAlpha();
@@ -56,12 +56,12 @@ namespace WebCore {
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator);
private:
- StillImage(const QImage&);
- StillImage(const QImage*);
+ StillImage(const QPixmap&);
+ StillImage(const QPixmap*);
virtual ~StillImage();
- const QImage* m_image;
- bool m_ownsImage;
+ const QPixmap* m_pixmap;
+ bool m_ownsPixmap;
};
}
diff --git a/Source/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp b/Source/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
index 7ff432b17..73a0e414f 100644
--- a/Source/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
@@ -27,8 +27,8 @@
#include "AffineTransform.h"
#include "TransformationMatrix.h"
-#include "IntRect.h"
#include "FloatRect.h"
+#include "IntRect.h"
namespace WebCore {
diff --git a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
index 5974017be..f13deb03b 100644
--- a/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
+++ b/Source/WebCore/platform/graphics/qt/TransparencyLayer.h
@@ -36,24 +36,24 @@
#ifndef TransparencyLayer_h
#define TransparencyLayer_h
-#include <NativeImageQt.h>
#include <QPaintEngine>
#include <QPainter>
+#include <QPixmap>
namespace WebCore {
struct TransparencyLayer {
WTF_MAKE_FAST_ALLOCATED;
public:
- TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QImage& alphaMask)
- : image(rect.width(), rect.height(), NativeImageQt::defaultFormatForAlphaEnabledImages())
+ TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QPixmap& alphaMask)
+ : pixmap(rect.width(), rect.height())
, opacity(opacity)
, alphaMask(alphaMask)
, saveCounter(1) // see the comment for saveCounter
{
offset = rect.topLeft();
- image.fill(Qt::transparent);
- painter.begin(&image);
+ pixmap.fill(Qt::transparent);
+ painter.begin(&pixmap);
painter.setRenderHints(p->renderHints());
painter.translate(-offset);
painter.setPen(p->pen());
@@ -67,12 +67,12 @@ public:
{
}
- QImage image;
+ QPixmap pixmap;
QPoint offset;
QPainter painter;
qreal opacity;
// for clipToImageBuffer
- QImage alphaMask;
+ QPixmap alphaMask;
// saveCounter is only used in combination with alphaMask
// otherwise, its value is unspecified
int saveCounter;
diff --git a/Source/WebCore/platform/graphics/skia/FontCacheSkia.cpp b/Source/WebCore/platform/graphics/skia/FontCacheSkia.cpp
index 271c3d7e9..336abc430 100644
--- a/Source/WebCore/platform/graphics/skia/FontCacheSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/FontCacheSkia.cpp
@@ -30,20 +30,16 @@
#include "config.h"
#include "FontCache.h"
-
#include "Font.h"
#include "FontDescription.h"
#include "FontFamily.h"
#include "FontPlatformData.h"
#include "Logging.h"
#include "NotImplemented.h"
-#include "PlatformSupport.h"
#include "SimpleFontData.h"
-
#include "SkPaint.h"
#include "SkTypeface.h"
#include "SkUtils.h"
-
#include <unicode/locid.h>
#include <wtf/Assertions.h>
#include <wtf/text/AtomicString.h>
@@ -55,9 +51,7 @@ void FontCache::platformInit()
{
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
- const UChar* characters,
- int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
icu::Locale locale = icu::Locale::getDefault();
FontCache::SimpleFontFamily family;
@@ -94,12 +88,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
return getCachedFontData(&platformData, DoNotRetain);
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{
DEFINE_STATIC_LOCAL(const AtomicString, sansStr, ("Sans"));
DEFINE_STATIC_LOCAL(const AtomicString, serifStr, ("Serif"));
diff --git a/Source/WebCore/platform/graphics/skia/FontSkia.cpp b/Source/WebCore/platform/graphics/skia/FontSkia.cpp
index 03f1417fb..c8097e349 100644
--- a/Source/WebCore/platform/graphics/skia/FontSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/FontSkia.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "Font.h"
+#include "FontSmoothingMode.h"
#include "GlyphBuffer.h"
#include "GraphicsContext.h"
#include "LayoutTestSupport.h"
@@ -71,6 +72,16 @@ static void setupPaint(SkPaint* paint, const SimpleFontData* fontData, const Fon
paint->setAutohinted(false); // freetype specific
paint->setLCDRenderText(shouldSmoothFonts);
paint->setSubpixelText(true);
+
+#if OS(DARWIN)
+ // When using CoreGraphics, disable hinting when webkit-font-smoothing:antialiased is used.
+ // See crbug.com/152304
+ if (font->fontDescription().fontSmoothing() == Antialiased)
+ paint->setHinting(SkPaint::kNo_Hinting);
+#endif
+
+ if (font->fontDescription().textRenderingMode() == GeometricPrecision)
+ paint->setHinting(SkPaint::kNo_Hinting);
}
// TODO: This needs to be split into helper functions to better scope the
@@ -120,8 +131,8 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
- x += SkFloatToScalar(adv[i].width);
- y += SkFloatToScalar(adv[i].height);
+ x += SkFloatToScalar(adv[i].width());
+ y += SkFloatToScalar(adv[i].height());
}
SkCanvas* canvas = gc->platformContext()->canvas();
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 35231a9da..fc9714671 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -83,11 +83,6 @@ inline int fastMod(int value, int max)
return value;
}
-inline float square(float n)
-{
- return n * n;
-}
-
} // namespace
// Local helper functions ------------------------------------------------------
@@ -121,6 +116,89 @@ void addCornerArc(SkPath* path, const SkRect& rect, const IntSize& size, int sta
path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false);
}
+void draw2xMarker(SkBitmap* bitmap, int index)
+{
+
+ static const SkPMColor lineColors[2] = {
+ SkPreMultiplyARGB(0xFF, 0xFF, 0x00, 0x00), // Opaque red.
+ SkPreMultiplyARGB(0xFF, 0xC0, 0xC0, 0xC0), // Opaque gray.
+ };
+ static const SkPMColor antiColors1[2] = {
+ SkPreMultiplyARGB(0xB0, 0xFF, 0x00, 0x00), // Semitransparent red
+ SkPreMultiplyARGB(0xB0, 0xC0, 0xC0, 0xC0), // Semitransparent gray
+ };
+ static const SkPMColor antiColors2[2] = {
+ SkPreMultiplyARGB(0x60, 0xFF, 0x00, 0x00), // More transparent red
+ SkPreMultiplyARGB(0x60, 0xC0, 0xC0, 0xC0), // More transparent gray
+ };
+
+ const SkPMColor lineColor = lineColors[index];
+ const SkPMColor antiColor1 = antiColors1[index];
+ const SkPMColor antiColor2 = antiColors2[index];
+
+ uint32_t* row1 = bitmap->getAddr32(0, 0);
+ uint32_t* row2 = bitmap->getAddr32(0, 1);
+ uint32_t* row3 = bitmap->getAddr32(0, 2);
+ uint32_t* row4 = bitmap->getAddr32(0, 3);
+
+ // Pattern: X0o o0X0o o0
+ // XX0o o0XXX0o o0X
+ // o0XXX0o o0XXX0o
+ // o0X0o o0X0o
+ const SkPMColor row1Color[] = { lineColor, antiColor1, antiColor2, 0, 0, 0, antiColor2, antiColor1 };
+ const SkPMColor row2Color[] = { lineColor, lineColor, antiColor1, antiColor2, 0, antiColor2, antiColor1, lineColor };
+ const SkPMColor row3Color[] = { 0, antiColor2, antiColor1, lineColor, lineColor, lineColor, antiColor1, antiColor2 };
+ const SkPMColor row4Color[] = { 0, 0, antiColor2, antiColor1, lineColor, antiColor1, antiColor2, 0 };
+
+ for (int x = 0; x < bitmap->width() + 8; x += 8) {
+ int count = min(bitmap->width() - x, 8);
+ if (count > 0) {
+ memcpy(row1 + x, row1Color, count * sizeof(SkPMColor));
+ memcpy(row2 + x, row2Color, count * sizeof(SkPMColor));
+ memcpy(row3 + x, row3Color, count * sizeof(SkPMColor));
+ memcpy(row4 + x, row4Color, count * sizeof(SkPMColor));
+ }
+ }
+}
+
+void draw1xMarker(SkBitmap* bitmap, int index)
+{
+ static const uint32_t lineColors[2] = {
+ 0xFF << SK_A32_SHIFT | 0xFF << SK_R32_SHIFT, // Opaque red.
+ 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Opaque gray.
+ };
+ static const uint32_t antiColors[2] = {
+ 0x60 << SK_A32_SHIFT | 0x60 << SK_R32_SHIFT, // Semitransparent red
+ 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Semitransparent gray
+ };
+
+ const uint32_t lineColor = lineColors[index];
+ const uint32_t antiColor = antiColors[index];
+
+ // Pattern: X o o X o o X
+ // o X o o X o
+ uint32_t* row1 = bitmap->getAddr32(0, 0);
+ uint32_t* row2 = bitmap->getAddr32(0, 1);
+ for (int x = 0; x < bitmap->width(); x++) {
+ switch (x % 4) {
+ case 0:
+ row1[x] = lineColor;
+ break;
+ case 1:
+ row1[x] = antiColor;
+ row2[x] = antiColor;
+ break;
+ case 2:
+ row2[x] = lineColor;
+ break;
+ case 3:
+ row1[x] = antiColor;
+ row2[x] = antiColor;
+ break;
+ }
+ }
+}
+
// -----------------------------------------------------------------------------
// This may be called with a NULL pointer to create a graphics context that has
@@ -522,92 +600,106 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& pt, float widt
if (paintingDisabled())
return;
+ int deviceScaleFactor = SkScalarRoundToInt(WebCoreFloatToSkScalar(platformContext()->deviceScaleFactor()));
+ ASSERT(deviceScaleFactor == 1 || deviceScaleFactor == 2);
+
// Create the pattern we'll use to draw the underline.
int index = style == DocumentMarkerGrammarLineStyle ? 1 : 0;
- static SkBitmap* misspellBitmap[2] = { 0, 0 };
+ static SkBitmap* misspellBitmap1x[2] = { 0, 0 };
+ static SkBitmap* misspellBitmap2x[2] = { 0, 0 };
+ SkBitmap** misspellBitmap = deviceScaleFactor == 2 ? misspellBitmap2x : misspellBitmap1x;
if (!misspellBitmap[index]) {
#if PLATFORM(CHROMIUM) && OS(DARWIN)
// Match the artwork used by the Mac.
- const int rowPixels = 4;
- const int colPixels = 3;
-#else
- // We use a 2-pixel-high misspelling indicator because that seems to be
- // what WebKit is designed for, and how much room there is in a typical
- // page for it.
- const int rowPixels = 32; // Must be multiple of 4 for pattern below.
- const int colPixels = 2;
-#endif
+ const int rowPixels = 4 * deviceScaleFactor;
+ const int colPixels = 3 * deviceScaleFactor;
misspellBitmap[index] = new SkBitmap;
misspellBitmap[index]->setConfig(SkBitmap::kARGB_8888_Config,
rowPixels, colPixels);
misspellBitmap[index]->allocPixels();
misspellBitmap[index]->eraseARGB(0, 0, 0, 0);
-#if PLATFORM(CHROMIUM) && OS(DARWIN)
- const uint32_t colors[2][6] = {
- { 0x2A2A0600, 0x57571000, 0xA8A81B00, 0xBFBF1F00, 0x70701200, 0xE0E02400 },
- { 0x2A001503, 0x57002A08, 0xA800540D, 0xBF005F0F, 0x70003809, 0xE0007012 }
- };
const uint32_t transparentColor = 0x00000000;
- // Pattern: a b a a b a
- // c d c c d c
- // e f e e f e
- for (int x = 0; x < colPixels; ++x) {
- uint32_t* row = misspellBitmap[index]->getAddr32(0, x);
- row[0] = colors[index][x * 2];
- row[1] = colors[index][x * 2 + 1];
- row[2] = colors[index][x * 2];
- row[3] = transparentColor;
- }
-#else
- static const uint32_t lineColors[2] = {
- 0xFF << SK_A32_SHIFT | 0xFF << SK_R32_SHIFT, // Opaque red.
- 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Opaque gray.
- };
- static const uint32_t antiColors[2] = {
- 0x60 << SK_A32_SHIFT | 0x60 << SK_R32_SHIFT, // Semitransparent red
- 0xFF << SK_A32_SHIFT | 0xC0 << SK_R32_SHIFT | 0xC0 << SK_G32_SHIFT | 0xC0 << SK_B32_SHIFT, // Semitransparent gray
- };
- const uint32_t lineColor = lineColors[index];
- const uint32_t antiColor = antiColors[index];
-
- // Pattern: X o o X o o X
- // o X o o X o
- uint32_t* row1 = misspellBitmap[index]->getAddr32(0, 0);
- uint32_t* row2 = misspellBitmap[index]->getAddr32(0, 1);
- for (int x = 0; x < rowPixels; x++) {
- switch (x % 4) {
- case 0:
- row1[x] = lineColor;
- break;
- case 1:
- row1[x] = antiColor;
- row2[x] = antiColor;
- break;
- case 2:
- row2[x] = lineColor;
- break;
- case 3:
- row1[x] = antiColor;
- row2[x] = antiColor;
- break;
+ if (deviceScaleFactor == 1) {
+ const uint32_t colors[2][6] = {
+ { 0x2A2A0600, 0x57571000, 0xA8A81B00, 0xBFBF1F00, 0x70701200, 0xE0E02400 },
+ { 0x2A001503, 0x57002A08, 0xA800540D, 0xBF005F0F, 0x70003809, 0xE0007012 }
+ };
+
+ // Pattern: a b a a b a
+ // c d c c d c
+ // e f e e f e
+ for (int x = 0; x < colPixels; ++x) {
+ uint32_t* row = misspellBitmap[index]->getAddr32(0, x);
+ row[0] = colors[index][x * 2];
+ row[1] = colors[index][x * 2 + 1];
+ row[2] = colors[index][x * 2];
+ row[3] = transparentColor;
}
- }
+ } else if (deviceScaleFactor == 2) {
+ const uint32_t colors[2][18] = {
+ { 0x0a090101, 0x33320806, 0x55540f0a, 0x37360906, 0x6e6c120c, 0x6e6c120c, 0x7674140d, 0x8d8b1810, 0x8d8b1810,
+ 0x96941a11, 0xb3b01f15, 0xb3b01f15, 0x6d6b130c, 0xd9d62619, 0xd9d62619, 0x19180402, 0x7c7a150e, 0xcecb2418 },
+ { 0x0a000400, 0x33031b06, 0x55062f0b, 0x37041e06, 0x6e083d0d, 0x6e083d0d, 0x7608410e, 0x8d094e11, 0x8d094e11,
+ 0x960a5313, 0xb30d6417, 0xb30d6417, 0x6d073c0d, 0xd90f781c, 0xd90f781c, 0x19010d03, 0x7c094510, 0xce0f731a }
+ };
+
+ // Pattern: a b c c b a
+ // d e f f e d
+ // g h j j h g
+ // k l m m l k
+ // n o p p o n
+ // q r s s r q
+ for (int x = 0; x < colPixels; ++x) {
+ uint32_t* row = misspellBitmap[index]->getAddr32(0, x);
+ row[0] = colors[index][x * 3];
+ row[1] = colors[index][x * 3 + 1];
+ row[2] = colors[index][x * 3 + 2];
+ row[3] = colors[index][x * 3 + 2];
+ row[4] = colors[index][x * 3 + 1];
+ row[5] = colors[index][x * 3];
+ row[6] = transparentColor;
+ row[7] = transparentColor;
+ }
+ } else
+ ASSERT_NOT_REACHED();
+#else
+ // We use a 2-pixel-high misspelling indicator because that seems to be
+ // what WebKit is designed for, and how much room there is in a typical
+ // page for it.
+ const int rowPixels = 32 * deviceScaleFactor; // Must be multiple of 4 for pattern below.
+ const int colPixels = 2 * deviceScaleFactor;
+ misspellBitmap[index] = new SkBitmap;
+ misspellBitmap[index]->setConfig(SkBitmap::kARGB_8888_Config, rowPixels, colPixels);
+ misspellBitmap[index]->allocPixels();
+
+ misspellBitmap[index]->eraseARGB(0, 0, 0, 0);
+ if (deviceScaleFactor == 1)
+ draw1xMarker(misspellBitmap[index], index);
+ else if (deviceScaleFactor == 2)
+ draw2xMarker(misspellBitmap[index], index);
+ else
+ ASSERT_NOT_REACHED();
#endif
}
- SkScalar originX = WebCoreFloatToSkScalar(pt.x());
#if PLATFORM(CHROMIUM) && OS(DARWIN)
- SkScalar originY = WebCoreFloatToSkScalar(pt.y());
+ SkScalar originX = WebCoreFloatToSkScalar(pt.x()) * deviceScaleFactor;
+ SkScalar originY = WebCoreFloatToSkScalar(pt.y()) * deviceScaleFactor;
+
// Make sure to draw only complete dots.
int rowPixels = misspellBitmap[index]->width();
- float widthMod = fmodf(width, rowPixels);
- if (rowPixels - widthMod > 1)
- width -= widthMod;
+ float widthMod = fmodf(width * deviceScaleFactor, rowPixels);
+ if (rowPixels - widthMod > deviceScaleFactor)
+ width -= widthMod / deviceScaleFactor;
#else
+ SkScalar originX = WebCoreFloatToSkScalar(pt.x());
+
// Offset it vertically by 1 so that there's some space under the text.
SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1;
+ originX *= deviceScaleFactor;
+ originY *= deviceScaleFactor;
#endif
// Make a shader for the bitmap with an origin of the box we'll draw. This
@@ -616,23 +708,26 @@ void GraphicsContext::drawLineForDocumentMarker(const FloatPoint& pt, float widt
*misspellBitmap[index], SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode);
SkMatrix matrix;
- matrix.reset();
- matrix.postTranslate(originX, originY);
+ matrix.setTranslate(originX, originY);
shader->setLocalMatrix(matrix);
// Assign the shader to the paint & release our reference. The paint will
// now own the shader and the shader will be destroyed when the paint goes
// out of scope.
SkPaint paint;
- paint.setShader(shader);
- shader->unref();
+ paint.setShader(shader)->unref();
SkRect rect;
- rect.set(originX,
- originY,
- originX + WebCoreFloatToSkScalar(width),
- originY + SkIntToScalar(misspellBitmap[index]->height()));
+ rect.set(originX, originY, originX + WebCoreFloatToSkScalar(width) * deviceScaleFactor, originY + SkIntToScalar(misspellBitmap[index]->height()));
+
+ if (deviceScaleFactor == 2) {
+ platformContext()->canvas()->save();
+ platformContext()->canvas()->scale(SK_ScalarHalf, SK_ScalarHalf);
+ }
platformContext()->canvas()->drawRect(rect, paint);
+ if (deviceScaleFactor == 2)
+ platformContext()->canvas()->restore();
+
platformContext()->didDrawRect(rect, paint);
}
diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 905480d10..82c367d29 100644
--- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -42,6 +42,7 @@
#include "ImageData.h"
#include "JPEGImageEncoder.h"
#include "MIMETypeRegistry.h"
+#include "MemoryInstrumentationSkia.h"
#include "PNGImageEncoder.h"
#include "PlatformContextSkia.h"
#include "SharedGraphicsContext3D.h"
@@ -373,6 +374,16 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo
return "data:" + mimeType + ";base64," + base64Data;
}
+void ImageBufferData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this);
+ info.addMember(m_canvas);
+ info.addMember(m_platformContext);
+#if USE(ACCELERATED_COMPOSITING)
+ info.addMember(m_layerBridge);
+#endif
+}
+
String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, const double* quality)
{
ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
index 8f883d819..e5a52411d 100644
--- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -40,6 +40,7 @@
#include "Logging.h"
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
+#include "SkBitmap.h"
#include "SkPixelRef.h"
#include "SkRect.h"
#include "SkShader.h"
@@ -50,6 +51,9 @@
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
+#include <limits>
+#include <math.h>
+
#if PLATFORM(CHROMIUM)
#include "TraceEvent.h"
#endif
@@ -70,11 +74,8 @@ enum ResamplingMode {
RESAMPLE_AWESOME,
};
-static ResamplingMode computeResamplingMode(const SkMatrix& matrix, const NativeImageSkia& bitmap, int srcWidth, int srcHeight, float destWidth, float destHeight)
+static ResamplingMode computeResamplingMode(const SkMatrix& matrix, const NativeImageSkia& bitmap, float srcWidth, float srcHeight, float destWidth, float destHeight)
{
- int destIWidth = static_cast<int>(destWidth);
- int destIHeight = static_cast<int>(destHeight);
-
// The percent change below which we will not resample. This usually means
// an off-by-one error on the web page, and just doing nearest neighbor
// sampling is usually good enough.
@@ -92,10 +93,13 @@ static ResamplingMode computeResamplingMode(const SkMatrix& matrix, const Native
// Figure out if we should resample this image. We try to prune out some
// common cases where resampling won't give us anything, since it is much
// slower than drawing stretched.
- if (srcWidth == destIWidth && srcHeight == destIHeight) {
- // We don't need to resample if the source and destination are the same.
+ float diffWidth = fabs(destWidth - srcWidth);
+ float diffHeight = fabs(destHeight - srcHeight);
+ bool widthNearlyEqual = diffWidth < std::numeric_limits<float>::epsilon();
+ bool heightNearlyEqual = diffHeight < std::numeric_limits<float>::epsilon();
+ // We don't need to resample if the source and destination are the same.
+ if (widthNearlyEqual && heightNearlyEqual)
return RESAMPLE_NONE;
- }
if (srcWidth <= kSmallImageSizeThreshold
|| srcHeight <= kSmallImageSizeThreshold
@@ -113,7 +117,7 @@ static ResamplingMode computeResamplingMode(const SkMatrix& matrix, const Native
// This is trying to catch cases where somebody has created a border
// (which might be large) and then is stretching it to fill some part
// of the page.
- if (srcWidth == destWidth || srcHeight == destHeight)
+ if (widthNearlyEqual || heightNearlyEqual)
return RESAMPLE_NONE;
// The image is growing a lot and in more than one direction. Resampling
@@ -121,8 +125,8 @@ static ResamplingMode computeResamplingMode(const SkMatrix& matrix, const Native
return RESAMPLE_LINEAR;
}
- if ((fabs(destWidth - srcWidth) / srcWidth < kFractionalChangeThreshold)
- && (fabs(destHeight - srcHeight) / srcHeight < kFractionalChangeThreshold)) {
+ if ((diffWidth / srcWidth < kFractionalChangeThreshold)
+ && (diffHeight / srcHeight < kFractionalChangeThreshold)) {
// It is disappointingly common on the web for image sizes to be off by
// one or two pixels. We don't bother resampling if the size difference
// is a small fraction of the original size.
@@ -162,11 +166,127 @@ static ResamplingMode limitResamplingMode(PlatformContextSkia* platformContext,
return resampling;
}
-// Draws the given bitmap to the given canvas. The subset of the source bitmap
-// identified by src_rect is drawn to the given destination rect. The bitmap
-// will be resampled to resample_width * resample_height (this is the size of
-// the whole image, not the subset). See shouldResampleBitmap for more.
+// Return true if the rectangle is aligned to integer boundaries.
+// See comments for computeBitmapDrawRects() for how this is used.
+static bool areBoundariesIntegerAligned(const SkRect& rect)
+{
+ // Value is 1.19209e-007. This is the tolerance threshold.
+ const float epsilon = std::numeric_limits<float>::epsilon();
+ SkIRect roundedRect = roundedIntRect(rect);
+
+ return fabs(rect.x() - roundedRect.x()) < epsilon
+ && fabs(rect.y() - roundedRect.y()) < epsilon
+ && fabs(rect.right() - roundedRect.right()) < epsilon
+ && fabs(rect.bottom() - roundedRect.bottom()) < epsilon;
+}
+
+// FIXME: Remove this code when SkCanvas accepts SkRect as source rectangle.
+// See crbug.com/117597 for background.
+//
+// WebKit wants to draw a sub-rectangle (FloatRect) in a bitmap and scale it to
+// another FloatRect. However Skia only allows bitmap to be addressed by a
+// IntRect. This function computes the appropriate IntRect that encloses the
+// source rectangle and the corresponding enclosing destination rectangle,
+// while maintaining the scale factor.
+//
+// |srcRect| is the source rectangle in the bitmap. Return true if fancy
+// alignment is required. User of this function needs to clip to |dstRect|.
+// Return false if clipping is not needed.
+//
+// |dstRect| is the input rectangle that |srcRect| is scaled to.
+//
+// |outSrcRect| and |outDstRect| are the corresponding output rectangles.
+//
+// ALGORITHM
+//
+// The objective is to (a) find an enclosing IntRect for the source rectangle
+// and (b) the corresponding FloatRect in destination space.
+//
+// These are the steps performed:
+//
+// 1. IntRect enclosingSrcRect = enclosingIntRect(srcRect)
+//
+// Compute the enclosing IntRect for |srcRect|. This ensures the bitmap
+// image is addressed with integer boundaries.
+//
+// 2. FloatRect enclosingDestRect = mapSrcToDest(enclosingSrcRect)
+//
+// Map the enclosing source rectangle to destination coordinate space.
+//
+// The output will be enclosingSrcRect and enclosingDestRect from the
+// algorithm above.
+static bool computeBitmapDrawRects(const SkISize& bitmapSize, const SkRect& srcRect, const SkRect& dstRect, SkIRect* outSrcRect, SkRect* outDstRect)
+{
+ if (areBoundariesIntegerAligned(srcRect)) {
+ *outSrcRect = roundedIntRect(srcRect);
+ *outDstRect = dstRect;
+ return false;
+ }
+
+ SkIRect bitmapRect = SkIRect::MakeSize(bitmapSize);
+ SkIRect enclosingSrcRect = enclosingIntRect(srcRect);
+ enclosingSrcRect.intersect(bitmapRect); // Clip to bitmap rectangle.
+ SkRect enclosingDstRect;
+ enclosingDstRect.set(enclosingSrcRect);
+ SkMatrix transform;
+ transform.setRectToRect(srcRect, dstRect, SkMatrix::kFill_ScaleToFit);
+ transform.mapRect(&enclosingDstRect);
+ *outSrcRect = enclosingSrcRect;
+ *outDstRect = enclosingDstRect;
+ return true;
+}
+
+// This function is used to scale an image and extract a scaled fragment.
//
+// ALGORITHM
+//
+// Because the scaled image size has to be integers, we approximate the real
+// scale with the following formula (only X direction is shown):
+//
+// scaledImageWidth = round(scaleX * imageRect.width())
+// approximateScaleX = scaledImageWidth / imageRect.width()
+//
+// With this method we maintain a constant scale factor among fragments in
+// the scaled image. This allows fragments to stitch together to form the
+// full scaled image. The downside is there will be a small difference
+// between |scaleX| and |approximateScaleX|.
+//
+// A scaled image fragment is identified by:
+//
+// - Scaled image size
+// - Scaled image fragment rectangle (IntRect)
+//
+// Scaled image size has been determined and the next step is to compute the
+// rectangle for the scaled image fragment which needs to be an IntRect.
+//
+// scaledSrcRect = srcRect * (approximateScaleX, approximateScaleY)
+// enclosingScaledSrcRect = enclosingIntRect(scaledSrcRect)
+//
+// Finally we extract the scaled image fragment using
+// (scaledImageSize, enclosingScaledSrcRect).
+//
+static SkBitmap extractScaledImageFragment(const NativeImageSkia& bitmap, const SkRect& srcRect, float scaleX, float scaleY, SkRect* scaledSrcRect, SkIRect* enclosingScaledSrcRect)
+{
+ SkISize imageSize = SkISize::Make(bitmap.bitmap().width(), bitmap.bitmap().height());
+ SkISize scaledImageSize = SkISize::Make(clampToInteger(roundf(imageSize.width() * scaleX)),
+ clampToInteger(roundf(imageSize.height() * scaleY)));
+
+ SkRect imageRect = SkRect::MakeWH(imageSize.width(), imageSize.height());
+ SkRect scaledImageRect = SkRect::MakeWH(scaledImageSize.width(), scaledImageSize.height());
+
+ SkMatrix scaleTransform;
+ scaleTransform.setRectToRect(imageRect, scaledImageRect, SkMatrix::kFill_ScaleToFit);
+ scaleTransform.mapRect(scaledSrcRect, srcRect);
+
+ scaledSrcRect->intersect(scaledImageRect);
+ *enclosingScaledSrcRect = enclosingIntRect(*scaledSrcRect);
+
+ // |enclosingScaledSrcRect| can be larger than |scaledImageSize| because
+ // of float inaccuracy so clip to get inside.
+ enclosingScaledSrcRect->intersect(SkIRect::MakeSize(scaledImageSize));
+ return bitmap.resizedBitmap(scaledImageSize, *enclosingScaledSrcRect);
+}
+
// This does a lot of computation to resample only the portion of the bitmap
// that will only be drawn. This is critical for performance since when we are
// scrolling, for example, we are only drawing a small strip of the image.
@@ -175,48 +295,62 @@ static ResamplingMode limitResamplingMode(PlatformContextSkia* platformContext,
//
// Note: this code is only used when the canvas transformation is limited to
// scaling or translation.
-static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeImageSkia& bitmap, const SkIRect& srcIRect, const SkRect& destRect)
+static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeImageSkia& bitmap, const SkRect& srcRect, const SkRect& destRect)
{
#if PLATFORM(CHROMIUM)
TRACE_EVENT0("skia", "drawResampledBitmap");
#endif
- // Apply forward transform to destRect to estimate required size of
- // re-sampled bitmap, and use only in calls required to resize, or that
- // check for the required size.
- SkRect destRectTransformed;
- canvas.getTotalMatrix().mapRect(&destRectTransformed, destRect);
- SkIRect destRectTransformedRounded;
- destRectTransformed.round(&destRectTransformedRounded);
-
- // Compute the visible portion of our rect.
+ // We want to scale |destRect| with transformation in the canvas to obtain
+ // the final scale. The final scale is a combination of scale transform
+ // in canvas and explicit scaling (srcRect and destRect).
+ SkRect screenRect;
+ canvas.getTotalMatrix().mapRect(&screenRect, destRect);
+ float realScaleX = screenRect.width() / srcRect.width();
+ float realScaleY = screenRect.height() / srcRect.height();
+
+ // This part of code limits scaling only to visible portion in the
SkRect destRectVisibleSubset;
ClipRectToCanvas(canvas, destRect, &destRectVisibleSubset);
+
// ClipRectToCanvas often overshoots, resulting in a larger region than our
// original destRect. Intersecting gets us back inside.
if (!destRectVisibleSubset.intersect(destRect))
return; // Nothing visible in destRect.
- // Compute the transformed (screen space) portion of the visible portion for
- // use below.
- SkRect destRectVisibleSubsetTransformed;
- canvas.getTotalMatrix().mapRect(&destRectVisibleSubsetTransformed, destRectVisibleSubset);
- SkRect destBitmapSubsetTransformed = destRectVisibleSubsetTransformed;
- destBitmapSubsetTransformed.offset(-destRectTransformed.fLeft,
- -destRectTransformed.fTop);
- SkIRect destBitmapSubsetTransformedRounded;
- destBitmapSubsetTransformed.round(&destBitmapSubsetTransformedRounded);
-
- // Transforms above plus rounding may cause destBitmapSubsetTransformedRounded
- // to go outside the image, so need to clip to avoid problems.
- if (!destBitmapSubsetTransformedRounded.intersect(
- 0, 0, destRectTransformedRounded.width(), destRectTransformedRounded.height()))
- return; // Image is not visible.
-
- SkBitmap resampled = bitmap.resizedBitmap(srcIRect,
- destRectTransformedRounded.width(),
- destRectTransformedRounded.height(),
- destBitmapSubsetTransformedRounded);
- canvas.drawBitmapRect(resampled, 0, destRectVisibleSubset, &paint);
+ // Find the corresponding rect in the source image.
+ SkMatrix destToSrcTransform;
+ SkRect srcRectVisibleSubset;
+ destToSrcTransform.setRectToRect(destRect, srcRect, SkMatrix::kFill_ScaleToFit);
+ destToSrcTransform.mapRect(&srcRectVisibleSubset, destRectVisibleSubset);
+
+ SkRect scaledSrcRect;
+ SkIRect enclosingScaledSrcRect;
+ SkBitmap scaledImageFragment = extractScaledImageFragment(bitmap, srcRectVisibleSubset, realScaleX, realScaleY, &scaledSrcRect, &enclosingScaledSrcRect);
+
+ // Expand the destination rectangle because the source rectangle was
+ // expanded to fit to integer boundaries.
+ SkMatrix scaledSrcToDestTransform;
+ scaledSrcToDestTransform.setRectToRect(scaledSrcRect, destRectVisibleSubset, SkMatrix::kFill_ScaleToFit);
+ SkRect enclosingDestRect;
+ enclosingDestRect.set(enclosingScaledSrcRect);
+ scaledSrcToDestTransform.mapRect(&enclosingDestRect);
+
+ // The reason we do clipping is because Skia doesn't support SkRect as
+ // source rect. See http://crbug.com/145540.
+ // When Skia supports then use this as the source rect to replace 0.
+ //
+ // scaledSrcRect.offset(-enclosingScaledSrcRect.x(), -enclosingScaledSrcRect.y());
+ canvas.save();
+ canvas.clipRect(destRectVisibleSubset);
+
+ // Because the image fragment is generated with an approxmiated scaling
+ // factor. This draw will perform a close to 1 scaling.
+ //
+ // NOTE: For future optimization. If the difference in scale is so small
+ // that Skia doesn't produce a difference then we can just blit it directly
+ // to enhance performance.
+ canvas.drawBitmapRect(scaledImageFragment, 0, enclosingDestRect, &paint);
+ canvas.restore();
}
static bool hasNon90rotation(PlatformContextSkia* context)
@@ -224,7 +358,7 @@ static bool hasNon90rotation(PlatformContextSkia* context)
return !context->canvas()->getTotalMatrix().rectStaysRect();
}
-static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp)
+static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp)
{
#if PLATFORM(CHROMIUM)
TRACE_EVENT0("skia", "paintSkBitmap");
@@ -249,8 +383,9 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
if (!(canvas->getTotalMatrix().getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
canvas->getTotalMatrix().mapRect(&destRectTarget, destRect);
- resampling = computeResamplingMode(canvas->getTotalMatrix(), bitmap, srcRect.width(), srcRect.height(),
- SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height()));
+ resampling = computeResamplingMode(canvas->getTotalMatrix(), bitmap,
+ SkScalarToFloat(srcRect.width()), SkScalarToFloat(srcRect.height()),
+ SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTarget.height()));
}
if (resampling == RESAMPLE_NONE) {
@@ -269,7 +404,27 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
// is something interesting going on with the matrix (like a rotation).
// Note: for serialization, we will want to subset the bitmap first so
// we don't send extra pixels.
- canvas->drawBitmapRect(bitmap.bitmap(), &srcRect, destRect, &paint);
+ SkIRect enclosingSrcRect;
+ SkRect enclosingDestRect;
+ SkISize bitmapSize = SkISize::Make(bitmap.bitmap().width(), bitmap.bitmap().height());
+ bool needsClipping = computeBitmapDrawRects(bitmapSize, srcRect, destRect, &enclosingSrcRect, &enclosingDestRect);
+
+ if (enclosingSrcRect.isEmpty() || enclosingDestRect.isEmpty())
+ return;
+
+ // If destination is enlarged because source rectangle didn't align to
+ // integer boundaries then we draw a slightly larger rectangle and clip
+ // to the original destination rectangle.
+ // See http://crbug.com/145540.
+ if (needsClipping) {
+ platformContext->save();
+ platformContext->canvas()->clipRect(destRect);
+ }
+
+ canvas->drawBitmapRect(bitmap.bitmap(), &enclosingSrcRect, enclosingDestRect, &paint);
+
+ if (needsClipping)
+ platformContext->restore();
}
platformContext->didDrawRect(destRect, paint, &bitmap.bitmap());
}
@@ -323,7 +478,6 @@ void Image::drawPattern(GraphicsContext* context,
if (!bitmap)
return;
- SkIRect srcRect = enclosingIntRect(normSrcRect);
SkMatrix ctm = context->platformContext()->canvas()->getTotalMatrix();
SkMatrix totalMatrix;
totalMatrix.setConcat(ctm, patternTransform);
@@ -342,7 +496,7 @@ void Image::drawPattern(GraphicsContext* context,
if (context->platformContext()->isAccelerated() || context->platformContext()->printing())
resampling = RESAMPLE_LINEAR;
else
- resampling = computeResamplingMode(totalMatrix, *bitmap, srcRect.width(), srcRect.height(), destBitmapWidth, destBitmapHeight);
+ resampling = computeResamplingMode(totalMatrix, *bitmap, normSrcRect.width(), normSrcRect.height(), destBitmapWidth, destBitmapHeight);
resampling = limitResamplingMode(context->platformContext(), resampling);
// Load the transform WebKit requested.
@@ -351,12 +505,19 @@ void Image::drawPattern(GraphicsContext* context,
SkShader* shader;
if (resampling == RESAMPLE_AWESOME) {
// Do nice resampling.
- int width = static_cast<int>(destBitmapWidth);
- int height = static_cast<int>(destBitmapHeight);
- SkBitmap resampled = bitmap->resizedBitmap(srcRect, width, height);
+ float scaleX = destBitmapWidth / normSrcRect.width();
+ float scaleY = destBitmapHeight / normSrcRect.height();
+ SkRect scaledSrcRect;
+ SkIRect enclosingScaledSrcRect;
+
+ // The image fragment generated here is not exactly what is
+ // requested. The scale factor used is approximated and image
+ // fragment is slightly larger to align to integer
+ // boundaries.
+ SkBitmap resampled = extractScaledImageFragment(*bitmap, normSrcRect, scaleX, scaleY, &scaledSrcRect, &enclosingScaledSrcRect);
shader = SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
- // Since we just resized the bitmap, we need to remove the scale
+ // Since we just resized the bitmap, we need to remove the scale
// applied to the pixels in the bitmap shader. This means we need
// CTM * patternTransform to have identity scale. Since we
// can't modify CTM (or the rectangle will be drawn in the wrong
@@ -367,7 +528,7 @@ void Image::drawPattern(GraphicsContext* context,
} else {
// No need to do nice resampling.
SkBitmap srcSubset;
- bitmap->bitmap().extractSubset(&srcSubset, srcRect);
+ bitmap->bitmap().extractSubset(&srcSubset, enclosingIntRect(normSrcRect));
shader = SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
}
@@ -443,10 +604,10 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
return; // Nothing to draw.
paintSkBitmap(ctxt->platformContext(),
- *bm,
- enclosingIntRect(normSrcRect),
- normDstRect,
- WebCoreCompositeToSkiaComposite(compositeOp));
+ *bm,
+ normSrcRect,
+ normDstRect,
+ WebCoreCompositeToSkiaComposite(compositeOp));
if (ImageObserver* observer = imageObserver())
observer->didDraw(this);
@@ -467,10 +628,10 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
return; // Nothing to draw.
paintSkBitmap(ctxt->platformContext(),
- m_nativeImage,
- enclosingIntRect(normSrcRect),
- normDstRect,
- WebCoreCompositeToSkiaComposite(compositeOp));
+ m_nativeImage,
+ normSrcRect,
+ normDstRect,
+ WebCoreCompositeToSkiaComposite(compositeOp));
if (ImageObserver* observer = imageObserver())
observer->didDraw(this);
diff --git a/Source/WebCore/platform/text/LocalizedNumberICU.cpp b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp
index 17cf7edb3..0793c3569 100644
--- a/Source/WebCore/platform/text/LocalizedNumberICU.cpp
+++ b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -29,28 +29,31 @@
*/
#include "config.h"
+#include "MemoryInstrumentationSkia.h"
-#include "LocaleICU.h"
-#include "LocalizedNumber.h"
+#include "PlatformMemoryInstrumentation.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkPixelRef.h"
-namespace WebCore {
-
-String convertToLocalizedNumber(const String& canonicalNumberString)
+void reportMemoryUsage(const SkBitmap* const& image, WTF::MemoryObjectInfo* memoryObjectInfo)
{
- return LocaleICU::currentLocale()->convertToLocalizedNumber(canonicalNumberString);
+ WTF::MemoryClassInfo info(memoryObjectInfo, image);
+ SkPixelRef* pixelRef = image->pixelRef();
+ info.addMember(pixelRef);
+ if (pixelRef)
+ info.addRawBuffer(pixelRef->pixels(), image->getSize());
}
-String convertFromLocalizedNumber(const String& localizedNumberString)
+void reportMemoryUsage(const SkDevice* const& device, WTF::MemoryObjectInfo* memoryObjectInfo)
{
- return LocaleICU::currentLocale()->convertFromLocalizedNumber(localizedNumberString);
+ WTF::MemoryClassInfo info(memoryObjectInfo, device);
+ info.addMember(const_cast<SkDevice*>(device)->accessBitmap(false));
}
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-
-String localizedDecimalSeparator()
+void reportMemoryUsage(const SkCanvas* const& canvas, WTF::MemoryObjectInfo* memoryObjectInfo)
{
- return LocaleICU::currentLocale()->localizedDecimalSeparator();
+ WTF::MemoryClassInfo info(memoryObjectInfo, canvas);
+ info.addMember(canvas->getDevice());
}
-
-#endif
-} // namespace WebCore
diff --git a/Source/WebCore/platform/text/LocalizedNumberNone.cpp b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h
index 94855b6e2..e6f81b0d2 100644
--- a/Source/WebCore/platform/text/LocalizedNumberNone.cpp
+++ b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -28,32 +28,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "LocalizedNumber.h"
+#ifndef MemoryInstrumentationSkia_h
+#define MemoryInstrumentationSkia_h
-#include <limits>
+#include "PlatformMemoryInstrumentation.h"
-using namespace std;
+class SkBitmap;
+class SkDevice;
+class SkCanvas;
-namespace WebCore {
+void reportMemoryUsage(const SkBitmap* const&, WTF::MemoryObjectInfo*);
+void reportMemoryUsage(const SkDevice* const&, WTF::MemoryObjectInfo*);
+void reportMemoryUsage(const SkCanvas* const&, WTF::MemoryObjectInfo*);
-String convertToLocalizedNumber(const String& canonicalNumberString)
-{
- return canonicalNumberString;
-}
-
-String convertFromLocalizedNumber(const String& localizedNumberString)
-{
- return localizedNumberString;
-}
-
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-
-UChar localizedDecimalSeparator()
-{
- return '.';
-}
-
-#endif
-
-} // namespace WebCore
+#endif // !defined(MemoryInstrumentationSkia_h)
diff --git a/Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp b/Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp
index 2c4baed75..1862a2afc 100644
--- a/Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp
@@ -34,7 +34,10 @@
#include "NativeImageSkia.h"
#include "GraphicsContext3D.h"
+#include "MemoryInstrumentationSkia.h"
#include "PlatformInstrumentation.h"
+#include "PlatformMemoryInstrumentation.h"
+#include "SkPixelRef.h"
#include "SkiaUtils.h"
namespace WebCore {
@@ -61,56 +64,48 @@ int NativeImageSkia::decodedSize() const
return m_image.getSize() + m_resizedImage.getSize();
}
-bool NativeImageSkia::hasResizedBitmap(const SkIRect& srcSubset, int destWidth, int destHeight) const
+bool NativeImageSkia::hasResizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
{
- return m_cachedImageInfo.isEqual(srcSubset, destWidth, destHeight) && !m_resizedImage.empty();
+ bool imageScaleEqual = m_cachedImageInfo.scaledImageSize == scaledImageSize;
+ bool scaledImageSubsetAvailable = m_cachedImageInfo.scaledImageSubset.contains(scaledImageSubset);
+ return imageScaleEqual && scaledImageSubsetAvailable && !m_resizedImage.empty();
}
-SkBitmap NativeImageSkia::resizedBitmap(const SkIRect& srcSubset,
- int destWidth,
- int destHeight,
- const SkIRect& destVisibleSubset) const
+SkBitmap NativeImageSkia::resizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
{
- if (!hasResizedBitmap(srcSubset, destWidth, destHeight)) {
+ if (!hasResizedBitmap(scaledImageSize, scaledImageSubset)) {
bool shouldCache = isDataComplete()
- && shouldCacheResampling(srcSubset, destWidth, destHeight, destVisibleSubset);
-
- SkBitmap subset;
- m_image.extractSubset(&subset, srcSubset);
- if (!shouldCache) {
- // Just resize the visible subset and return it.
- PlatformInstrumentation::willResizeImage(shouldCache);
- SkBitmap resizedImage = skia::ImageOperations::Resize(subset, skia::ImageOperations::RESIZE_LANCZOS3, destWidth, destHeight, destVisibleSubset);
- PlatformInstrumentation::didResizeImage();
- resizedImage.setImmutable();
+ && shouldCacheResampling(scaledImageSize, scaledImageSubset);
+
+ PlatformInstrumentation::willResizeImage(shouldCache);
+ SkBitmap resizedImage = skia::ImageOperations::Resize(m_image, skia::ImageOperations::RESIZE_LANCZOS3, scaledImageSize.width(), scaledImageSize.height(), scaledImageSubset);
+ resizedImage.setImmutable();
+ PlatformInstrumentation::didResizeImage();
+
+ if (!shouldCache)
return resizedImage;
- } else {
- PlatformInstrumentation::willResizeImage(shouldCache);
- m_resizedImage = skia::ImageOperations::Resize(subset, skia::ImageOperations::RESIZE_LANCZOS3, destWidth, destHeight);
- PlatformInstrumentation::didResizeImage();
- }
- m_resizedImage.setImmutable();
+
+ m_resizedImage = resizedImage;
}
- SkBitmap visibleBitmap;
- m_resizedImage.extractSubset(&visibleBitmap, destVisibleSubset);
- return visibleBitmap;
+ SkBitmap resizedSubset;
+ SkIRect resizedSubsetRect = m_cachedImageInfo.rectInSubset(scaledImageSubset);
+ m_resizedImage.extractSubset(&resizedSubset, resizedSubsetRect);
+ return resizedSubset;
}
-bool NativeImageSkia::shouldCacheResampling(const SkIRect& srcSubset,
- int destWidth,
- int destHeight,
- const SkIRect& destVisibleSubset) const
+bool NativeImageSkia::shouldCacheResampling(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const
{
// Check whether the requested dimensions match previous request.
- bool matchesPreviousRequest = m_cachedImageInfo.isEqual(srcSubset, destWidth, destHeight);
+ bool matchesPreviousRequest = m_cachedImageInfo.isEqual(scaledImageSize, scaledImageSubset);
if (matchesPreviousRequest)
++m_resizeRequests;
else {
- m_cachedImageInfo.set(srcSubset, destWidth, destHeight);
+ m_cachedImageInfo.set(scaledImageSize, scaledImageSubset);
m_resizeRequests = 0;
- // Reset m_resizedImage now, because we don't distinguish between the
- // last requested resize info and m_resizedImage's resize info.
+ // Reset m_resizedImage now, because we don't distinguish
+ // between the last requested resize info and m_resizedImage's
+ // resize info.
m_resizedImage.reset();
}
@@ -123,13 +118,16 @@ bool NativeImageSkia::shouldCacheResampling(const SkIRect& srcSubset,
// If the destination bitmap is excessively large, we'll never allow caching.
static const unsigned long long kLargeBitmapSize = 4096ULL * 4096ULL;
- if ((static_cast<unsigned long long>(destWidth) * static_cast<unsigned long long>(destHeight)) > kLargeBitmapSize)
+ unsigned long long fullSize = static_cast<unsigned long long>(scaledImageSize.width()) * static_cast<unsigned long long>(scaledImageSize.height());
+ unsigned long long fragmentSize = static_cast<unsigned long long>(scaledImageSubset.width()) * static_cast<unsigned long long>(scaledImageSubset.height());
+
+ if (fragmentSize > kLargeBitmapSize)
return false;
// If the destination bitmap is small, we'll always allow caching, since
// there is not very much penalty for computing it and it may come in handy.
- static const int kSmallBitmapSize = 4096;
- if (destWidth * destHeight <= kSmallBitmapSize)
+ static const unsigned kSmallBitmapSize = 4096;
+ if (fragmentSize <= kSmallBitmapSize)
return true;
// If "too many" requests have been made for this bitmap, we assume that
@@ -138,28 +136,46 @@ bool NativeImageSkia::shouldCacheResampling(const SkIRect& srcSubset,
if (m_resizeRequests >= kManyRequestThreshold)
return true;
- // If more than 1/4 of the resized image is visible, it's worth caching.
- int destVisibleSize = destVisibleSubset.width() * destVisibleSubset.height();
- return (destVisibleSize > (destWidth * destHeight) / 4);
+ // If more than 1/4 of the resized image is requested, it's worth caching.
+ return fragmentSize > fullSize / 4;
}
NativeImageSkia::CachedImageInfo::CachedImageInfo()
{
- srcSubset.setEmpty();
+ scaledImageSize.setEmpty();
+ scaledImageSubset.setEmpty();
+}
+
+bool NativeImageSkia::CachedImageInfo::isEqual(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset) const
+{
+ return scaledImageSize == otherScaledImageSize && scaledImageSubset == otherScaledImageSubset;
+}
+
+void NativeImageSkia::CachedImageInfo::set(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset)
+{
+ scaledImageSize = otherScaledImageSize;
+ scaledImageSubset = otherScaledImageSubset;
+}
+
+SkIRect NativeImageSkia::CachedImageInfo::rectInSubset(const SkIRect& otherScaledImageSubset)
+{
+ if (!scaledImageSubset.contains(otherScaledImageSubset))
+ return SkIRect::MakeEmpty();
+ SkIRect subsetRect = otherScaledImageSubset;
+ subsetRect.offset(-scaledImageSubset.x(), -scaledImageSubset.y());
+ return subsetRect;
}
-bool NativeImageSkia::CachedImageInfo::isEqual(const SkIRect& otherSrcSubset, int width, int height) const
+void NativeImageSkia::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
- return srcSubset == otherSrcSubset
- && requestSize.width() == width
- && requestSize.height() == height;
+ MemoryClassInfo info(memoryObjectInfo, this);
+ info.addMember(m_image);
+ info.addMember(m_resizedImage);
}
-void NativeImageSkia::CachedImageInfo::set(const SkIRect& otherSrcSubset, int width, int height)
+void reportMemoryUsage(const NativeImageSkia* const& image, MemoryObjectInfo* memoryObjectInfo)
{
- srcSubset = otherSrcSubset;
- requestSize.setWidth(width);
- requestSize.setHeight(height);
+ image->reportMemoryUsage(memoryObjectInfo);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/skia/NativeImageSkia.h b/Source/WebCore/platform/graphics/skia/NativeImageSkia.h
index 2a52e68ee..8b795e2a5 100644
--- a/Source/WebCore/platform/graphics/skia/NativeImageSkia.h
+++ b/Source/WebCore/platform/graphics/skia/NativeImageSkia.h
@@ -33,7 +33,8 @@
#include "SkBitmap.h"
#include "SkRect.h"
-#include "IntSize.h"
+#include "SkSize.h"
+#include <wtf/Forward.h>
namespace WebCore {
@@ -70,39 +71,35 @@ public:
float resolutionScale() const { return m_resolutionScale; }
// We can keep a resized version of the bitmap cached on this object.
- // This function will return true if there is a cached version of the
- // given image subset with the given dimensions and subsets.
- bool hasResizedBitmap(const SkIRect& srcSubset, int width, int height) const;
+ // This function will return true if there is a cached version of the given
+ // scale and subset.
+ bool hasResizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
// This will return an existing resized image subset, or generate a new one
- // of the specified size and subsets and possibly cache it.
- // srcSubset is the subset of the image to resize in image space.
- SkBitmap resizedBitmap(const SkIRect& srcSubset, int destWidth, int destHeight) const
- {
- SkIRect destVisibleSubset = {0, 0, destWidth, destHeight};
- return resizedBitmap(srcSubset, destWidth, destHeight, destVisibleSubset);
- }
-
- // Same as above, but returns a subset of the destination image (ie: the
- // visible subset). destVisibleSubset is the subset of the resized
- // (destWidth x destHeight) image.
- // In other words:
- // - crop image by srcSubset -> imageSubset.
- // - resize imageSubset to destWidth x destHeight -> destImage.
- // - return destImage cropped by destVisibleSubset.
- SkBitmap resizedBitmap(const SkIRect& srcSubset, int destWidth, int destHeight, const SkIRect& destVisibleSubset) const;
+ // of the specified size and subset and possibly cache it.
+ //
+ // scaledImageSize
+ // Dimensions of the scaled full image.
+ //
+ // scaledImageSubset
+ // Rectangle of the subset in the scaled image.
+ SkBitmap resizedBitmap(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
+
+ void reportMemoryUsage(MemoryObjectInfo*) const;
private:
// CachedImageInfo is used to uniquely identify cached or requested image
// resizes.
+ // Image resize is identified by the scaled image size and scaled image subset.
struct CachedImageInfo {
- IntSize requestSize;
- SkIRect srcSubset;
+ SkISize scaledImageSize;
+ SkIRect scaledImageSubset;
CachedImageInfo();
- bool isEqual(const SkIRect& otherSrcSubset, int width, int height) const;
- void set(const SkIRect& otherSrcSubset, int width, int height);
+ bool isEqual(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset) const;
+ void set(const SkISize& otherScaledImageSize, const SkIRect& otherScaledImageSubset);
+ SkIRect rectInSubset(const SkIRect& otherScaledImageRect);
};
// Returns true if the given resize operation should either resize the whole
@@ -118,16 +115,14 @@ private:
// better if we're going to be using it more than once (like a bitmap
// scrolling on and off the screen. Since we only cache when doing the
// entire thing, it's best to just do it up front.
- bool shouldCacheResampling(const SkIRect& srcSubset,
- int destWidth,
- int destHeight,
- const SkIRect& destSubset) const;
+ bool shouldCacheResampling(const SkISize& scaledImageSize, const SkIRect& scaledImageSubset) const;
// The original image.
SkBitmap m_image;
float m_resolutionScale;
- // The cached bitmap. This will be empty() if there is no cached image.
+ // The cached bitmap fragment. This is a subset of the scaled version of
+ // |m_image|. empty() returns true if there is no cached image.
mutable SkBitmap m_resizedImage;
// References how many times that the image size has been requested for
@@ -141,12 +136,11 @@ private:
// resized image, we know that we should probably cache it, even if all of
// those requests individually are small and would not otherwise be cached.
//
- // We also track the source and destination subsets for caching partial
- // image resizes.
+ // We also track scaling information and destination subset for the scaled
+ // image. See comments for CachedImageInfo.
mutable CachedImageInfo m_cachedImageInfo;
mutable int m_resizeRequests;
};
}
#endif // NativeImageSkia_h
-
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index a508a6e29..5d6bf936c 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -188,6 +188,7 @@ PlatformContextSkia::PlatformContextSkia(SkCanvas* canvas)
, m_accelerated(false)
, m_deferred(false)
, m_drawingToImageBuffer(false)
+ , m_deviceScaleFactor(1)
#if defined(SK_SUPPORT_HINTING_SCALE_FACTOR)
, m_hintingScaleFactor(SK_Scalar1)
#endif
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 8bc5f32e7..2369f3209 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -187,6 +187,9 @@ public:
bool isDeferred() const { return m_deferred; }
void setDeferred(bool deferred) { m_deferred = deferred; }
+ float deviceScaleFactor() const { return m_deviceScaleFactor; }
+ void setDeviceScaleFactor(float scale) { m_deviceScaleFactor = scale; }
+
void setTrackOpaqueRegion(bool track) { m_trackOpaqueRegion = track; }
// This will be an empty region unless tracking is enabled.
@@ -239,6 +242,7 @@ private:
bool m_accelerated;
bool m_deferred;
bool m_drawingToImageBuffer;
+ float m_deviceScaleFactor;
#if defined(SK_SUPPORT_HINTING_SCALE_FACTOR)
SkScalar m_hintingScaleFactor;
#endif
diff --git a/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp b/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
index 54486c3aa..4d32c74db 100644
--- a/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/SimpleFontDataSkia.cpp
@@ -42,6 +42,8 @@
#include "SkTypeface.h"
#include "SkTypes.h"
#include "VDMXParser.h"
+#include <unicode/normlzr.h>
+#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -110,16 +112,18 @@ void SimpleFontData::platformInit()
m_fontMetrics.setDescent(descent);
float xHeight;
- if (metrics.fXHeight)
+ if (metrics.fXHeight) {
xHeight = metrics.fXHeight;
- else {
- // hack taken from the Windows port
- xHeight = ascent * 0.56f;
+ m_fontMetrics.setXHeight(xHeight);
+ } else {
+ xHeight = ascent * 0.56; // Best guess from Windows font metrics.
+ m_fontMetrics.setXHeight(xHeight);
+ m_fontMetrics.setHasXHeight(false);
}
+
float lineGap = SkScalarToFloat(metrics.fLeading);
m_fontMetrics.setLineGap(lineGap);
- m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
@@ -159,6 +163,9 @@ void SimpleFontData::platformInit()
}
}
}
+
+ if (int unitsPerEm = paint.getTypeface()->getUnitsPerEm())
+ m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
void SimpleFontData::platformCharWidthInit()
@@ -170,30 +177,30 @@ void SimpleFontData::platformDestroy()
{
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
const float scaledSize = lroundf(fontDescription.computedSize() * scaleFactor);
- return adoptPtr(new SimpleFontData(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false));
+ return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize), isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFraction);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFraction);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
@@ -250,4 +257,32 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
return SkScalarToFloat(width);
}
+#if USE(HARFBUZZ_NG)
+bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const
+{
+ if (!m_combiningCharacterSequenceSupport)
+ m_combiningCharacterSequenceSupport = adoptPtr(new HashMap<String, bool>);
+
+ WTF::HashMap<String, bool>::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false);
+ if (!addResult.isNewEntry)
+ return addResult.iterator->value;
+
+ UErrorCode error = U_ZERO_ERROR;
+ Vector<UChar, 4> normalizedCharacters(length);
+ int32_t normalizedLength = unorm_normalize(characters, length, UNORM_NFC, UNORM_UNICODE_3_2, &normalizedCharacters[0], length, &error);
+ // Can't render if we have an error or no composition occurred.
+ if (U_FAILURE(error) || (static_cast<size_t>(normalizedLength) == length))
+ return false;
+
+ SkPaint paint;
+ m_platformData.setupPaint(&paint);
+ paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+ if (paint.textToGlyphs(&normalizedCharacters[0], normalizedLength * 2, 0)) {
+ addResult.iterator->value = true;
+ return true;
+ }
+ return false;
+}
+#endif
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp
index 9ff3881d0..c16a37799 100644
--- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp
@@ -25,7 +25,7 @@
#if USE(GRAPHICS_SURFACE)
namespace WebCore {
-PassRefPtr<GraphicsSurface> GraphicsSurface::create(const IntSize& size, Flags flags, uint64_t token)
+PassRefPtr<GraphicsSurface> GraphicsSurface::create(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
{
return platformImport(size, flags, token);
}
@@ -35,7 +35,7 @@ PassRefPtr<GraphicsSurface> GraphicsSurface::create(const IntSize& size, Graphic
return platformCreate(size, flags);
}
-uint64_t GraphicsSurface::exportToken()
+GraphicsSurfaceToken GraphicsSurface::exportToken()
{
return platformExport();
}
diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
index 0ee68cf3d..e78ebbc0e 100644
--- a/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
+++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
@@ -21,6 +21,7 @@
#define GraphicsSurface_h
#include "GraphicsContext.h"
+#include "GraphicsSurfaceToken.h"
#include "IntRect.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -32,7 +33,8 @@
#if OS(DARWIN)
typedef struct __IOSurface* IOSurfaceRef;
typedef IOSurfaceRef PlatformGraphicsSurface;
-#else
+#endif
+#if OS(LINUX)
typedef uint32_t PlatformGraphicsSurface;
#endif
@@ -69,13 +71,13 @@ public:
IntSize size() const { return m_size; }
static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags);
- static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags, uint64_t token);
+ static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags, const GraphicsSurfaceToken&);
void copyToGLTexture(uint32_t target, uint32_t texture, const IntRect& targetRect, const IntPoint& sourceOffset);
void copyFromFramebuffer(uint32_t fbo, const IntRect& sourceRect);
void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask);
uint32_t frontBuffer();
uint32_t swapBuffers();
- uint64_t exportToken();
+ GraphicsSurfaceToken exportToken();
uint32_t getTextureID();
PassOwnPtr<GraphicsContext> beginPaint(const IntRect&, LockOptions);
PassRefPtr<Image> createReadOnlyImage(const IntRect&);
@@ -83,8 +85,8 @@ public:
protected:
static PassRefPtr<GraphicsSurface> platformCreate(const IntSize&, Flags);
- static PassRefPtr<GraphicsSurface> platformImport(const IntSize&, Flags, uint64_t);
- uint64_t platformExport();
+ static PassRefPtr<GraphicsSurface> platformImport(const IntSize&, Flags, const GraphicsSurfaceToken&);
+ GraphicsSurfaceToken platformExport();
void platformDestroy();
uint32_t platformGetTextureID();
diff --git a/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h b/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h
new file mode 100644
index 000000000..45342f141
--- /dev/null
+++ b/Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2012 Digia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GraphicsSurfaceToken_h
+#define GraphicsSurfaceToken_h
+
+#include "GraphicsContext.h"
+#include "IntRect.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+#if USE(GRAPHICS_SURFACE)
+
+namespace WebCore {
+
+struct GraphicsSurfaceToken {
+
+typedef uint32_t BufferHandle;
+
+#if HAVE(GLX)
+ GraphicsSurfaceToken(uint32_t windowID = 0)
+ : frontBufferHandle(windowID)
+ { }
+
+ bool operator!=(const GraphicsSurfaceToken &rhs) const
+ {
+ return frontBufferHandle != rhs.frontBufferHandle;
+ }
+
+ bool isValid() const
+ {
+ return frontBufferHandle;
+ }
+
+#endif
+
+#if OS(DARWIN)
+ GraphicsSurfaceToken(BufferHandle frontBuffer = 0, BufferHandle backBuffer = 0)
+ : frontBufferHandle(frontBuffer)
+ , backBufferHandle(backBuffer)
+ { }
+
+ bool operator!=(const GraphicsSurfaceToken &rhs) const
+ {
+ return (frontBufferHandle != rhs.frontBufferHandle || backBufferHandle != rhs.backBufferHandle);
+ }
+
+ bool isValid() const
+ {
+ return frontBufferHandle && backBufferHandle;
+ }
+
+ BufferHandle backBufferHandle;
+#endif
+
+ BufferHandle frontBufferHandle;
+};
+
+}
+#endif // USE(GRAPHICS_SURFACE)
+
+#endif // GraphicsSurfaceToken_h
diff --git a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
index 8a8322df8..94c339176 100644
--- a/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
@@ -64,18 +64,13 @@ static uint32_t createTexture(IOSurfaceRef handle)
struct GraphicsSurfacePrivate {
public:
- GraphicsSurfacePrivate(uint64_t token)
+ GraphicsSurfacePrivate(const GraphicsSurfaceToken& token)
: m_token(token)
, m_frontBufferTexture(0)
, m_backBufferTexture(0)
{
- // The token contains the IOSurfaceID of the fist surface/buffer in the first 32 Bit
- // and the IOSurfaceID of the second surface/buffer in the second 32 Bit.
- uint32_t frontBuffer = token >> 32;
- uint32_t backBuffer = token & 0xffff;
-
- m_frontBuffer = IOSurfaceLookup(frontBuffer);
- m_backBuffer = IOSurfaceLookup(backBuffer);
+ m_frontBuffer = IOSurfaceLookup(m_token.frontBufferHandle);
+ m_backBuffer = IOSurfaceLookup(m_token.backBufferHandle);
}
GraphicsSurfacePrivate(const IntSize& size, GraphicsSurface::Flags flags)
@@ -119,11 +114,7 @@ public:
m_frontBuffer = IOSurfaceCreate(dict);
m_backBuffer = IOSurfaceCreate(dict);
- uint64_t token = IOSurfaceGetID(m_frontBuffer);
- token <<= 32;
- token |= IOSurfaceGetID(m_backBuffer);
-
- m_token = token;
+ m_token = GraphicsSurfaceToken(IOSurfaceGetID(m_frontBuffer), IOSurfaceGetID(m_backBuffer));
}
~GraphicsSurfacePrivate()
@@ -149,7 +140,7 @@ public:
return IOSurfaceGetID(m_frontBuffer);
}
- uint64_t token() const
+ GraphicsSurfaceToken token() const
{
return m_token;
}
@@ -185,10 +176,10 @@ private:
PlatformGraphicsSurface m_backBuffer;
uint32_t m_frontBufferTexture;
uint32_t m_backBufferTexture;
- uint64_t m_token;
+ GraphicsSurfaceToken m_token;
};
-uint64_t GraphicsSurface::platformExport()
+GraphicsSurfaceToken GraphicsSurface::platformExport()
{
return m_private->token();
}
@@ -276,7 +267,7 @@ PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size,
return surface;
}
-PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint64_t token)
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
{
// We currently disable support for CopyToTexture on Mac, because this is used for single buffered Tiles.
// The single buffered nature of this requires a call to glFlush, as described in platformCopyToTexture.
diff --git a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
index 1bbeb73b9..2fd6cba46 100644
--- a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
@@ -107,8 +107,18 @@ struct GraphicsSurfacePrivate {
, m_textureIsYInverted(false)
, m_hasAlpha(false)
{
+ QSurface* currentSurface = 0;
+ QOpenGLContext* currentContext = QOpenGLContext::currentContext();
+ if (currentContext)
+ currentSurface = currentContext->surface();
+
m_display = XOpenDisplay(0);
m_glContext->create();
+
+ // The GLX implementation of QOpenGLContext will reset the current context when create is being called.
+ // Therefore we have to make the previous context current again.
+ if (currentContext)
+ currentContext->makeCurrent(currentSurface);
}
~GraphicsSurfacePrivate()
@@ -237,9 +247,9 @@ static bool resolveGLMethods(GraphicsSurfacePrivate* p)
return resolved;
}
-uint64_t GraphicsSurface::platformExport()
+GraphicsSurfaceToken GraphicsSurface::platformExport()
{
- return m_platformSurface;
+ return GraphicsSurfaceToken(m_platformSurface);
}
uint32_t GraphicsSurface::platformGetTextureID()
@@ -316,7 +326,7 @@ PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size,
return surface;
}
-PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint64_t token)
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
{
// X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
// GraphicsSurfaceGLX uses an XWindow as native surface. This one always has a front and a back buffer.
@@ -330,7 +340,7 @@ PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size,
if (!resolveGLMethods(surface->m_private))
return PassRefPtr<GraphicsSurface>();
- surface->m_platformSurface = token;
+ surface->m_platformSurface = token.frontBufferHandle;
surface->m_private->createPixmap(surface->m_platformSurface);
surface->m_size = surface->m_private->size();
diff --git a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp
index e1b275893..734a093ae 100644
--- a/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp
+++ b/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceQt.cpp
@@ -52,7 +52,8 @@ PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect& rect)
int stride;
QImage::Format format = (flags() & SupportsAlpha) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
char* data = platformLock(rect, &stride, RetainPixels | ReadOnly);
- return BitmapImage::create(new QImage(reinterpret_cast<uchar*>(data), rect.width(), rect.height(), stride, format, didReleaseImage, this));
+ QImage image(reinterpret_cast<uchar*>(data), rect.width(), rect.height(), stride, format, didReleaseImage, this);
+ return BitmapImage::create(new QPixmap(QPixmap::fromImage(image)));
}
}
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
index f3b0eb411..42954a499 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
@@ -20,10 +20,19 @@
#include "config.h"
#include "GraphicsLayerTextureMapper.h"
+#include "GraphicsLayerFactory.h"
#include "TextureMapperLayer.h"
namespace WebCore {
+PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client)
+{
+ if (!factory)
+ return adoptPtr(new GraphicsLayerTextureMapper(client));
+
+ return factory->createGraphicsLayer(client);
+}
+
PassOwnPtr<GraphicsLayer> GraphicsLayer::create(GraphicsLayerClient* client)
{
if (s_graphicsLayerFactory)
@@ -47,7 +56,7 @@ void GraphicsLayerTextureMapper::notifyChange(TextureMapperLayer::ChangeMask cha
m_changeMask |= changeMask;
if (!client())
return;
- client()->notifySyncRequired(this);
+ client()->notifyFlushRequired(this);
}
void GraphicsLayerTextureMapper::didSynchronize()
@@ -358,16 +367,16 @@ void GraphicsLayerTextureMapper::setContentsToMedia(TextureMapperPlatformLayer*
/* \reimp (GraphicsLayer.h)
*/
-void GraphicsLayerTextureMapper::syncCompositingStateForThisLayerOnly()
+void GraphicsLayerTextureMapper::flushCompositingStateForThisLayerOnly()
{
- m_layer->syncCompositingState(this);
+ m_layer->flushCompositingState(this);
}
/* \reimp (GraphicsLayer.h)
*/
-void GraphicsLayerTextureMapper::syncCompositingState(const FloatRect&)
+void GraphicsLayerTextureMapper::flushCompositingState(const FloatRect&)
{
- m_layer->syncCompositingState(this, TextureMapperLayer::TraverseDescendants);
+ m_layer->flushCompositingState(this, TextureMapperLayer::TraverseDescendants);
}
bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
index 50070cc0f..637abd9d4 100644
--- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h
@@ -69,8 +69,8 @@ public:
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsToCanvas(PlatformLayer* canvas) { setContentsToMedia(canvas); }
- virtual void syncCompositingState(const FloatRect&);
- virtual void syncCompositingStateForThisLayerOnly();
+ virtual void flushCompositingState(const FloatRect&);
+ virtual void flushCompositingStateForThisLayerOnly();
virtual void setName(const String& name);
virtual PlatformLayer* platformLayer() const { return 0; }
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
index b4504682b..a90dbe4f1 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h
@@ -28,6 +28,9 @@
#define TEXMAP_OPENGL_ES_2
#endif
#endif
+#if PLATFORM(GTK) && USE(OPENGL_ES_2)
+#define TEXMAP_OPENGL_ES_2
+#endif
#include "FilterOperations.h"
#include "GraphicsContext.h"
@@ -84,7 +87,7 @@ public:
inline bool isOpaque() const { return !(m_flags & SupportsAlpha); }
#if ENABLE(CSS_FILTERS)
- virtual PassRefPtr<BitmapTexture> applyFilters(const BitmapTexture& contentTexture, const FilterOperations&) { return this; }
+ virtual PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const BitmapTexture& contentTexture, const FilterOperations&) { return this; }
#endif
protected:
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
index b25372ce6..995cc79da 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp
@@ -34,7 +34,7 @@
namespace WebCore {
#if USE(GRAPHICS_SURFACE)
-void TextureMapperSurfaceBackingStore::setGraphicsSurface(uint64_t graphicsSurfaceToken, const IntSize& surfaceSize, uint32_t frontBuffer)
+void TextureMapperSurfaceBackingStore::setGraphicsSurface(const GraphicsSurfaceToken& graphicsSurfaceToken, const IntSize& surfaceSize, uint32_t frontBuffer)
{
if (graphicsSurfaceToken != m_graphicsSurfaceToken) {
GraphicsSurface::Flags surfaceFlags = GraphicsSurface::SupportsTextureTarget
@@ -68,7 +68,7 @@ void TextureMapperSurfaceBackingStore::setSurface(PassRefPtr<GraphicsSurface> su
m_graphicsSurfaceToken = m_graphicsSurface->exportToken();
} else {
m_graphicsSurface = RefPtr<GraphicsSurface>();
- m_graphicsSurfaceToken = 0;
+ m_graphicsSurfaceToken = GraphicsSurfaceToken();
}
}
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
index 9d002b48e..93de3da06 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
@@ -50,7 +50,7 @@ protected:
class TextureMapperSurfaceBackingStore : public TextureMapperBackingStore {
public:
static PassRefPtr<TextureMapperSurfaceBackingStore> create() { return adoptRef(new TextureMapperSurfaceBackingStore); }
- void setGraphicsSurface(uint64_t graphicsSurfaceToken, const IntSize& surfaceSize, uint32_t frontBuffer);
+ void setGraphicsSurface(const GraphicsSurfaceToken&, const IntSize& surfaceSize, uint32_t frontBuffer);
PassRefPtr<WebCore::GraphicsSurface> graphicsSurface() const { return m_graphicsSurface; }
virtual PassRefPtr<BitmapTexture> texture() const;
virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*);
@@ -62,10 +62,9 @@ protected:
private:
TextureMapperSurfaceBackingStore()
: TextureMapperBackingStore()
- , m_graphicsSurfaceToken(0)
{ }
- uint64_t m_graphicsSurfaceToken;
+ GraphicsSurfaceToken m_graphicsSurfaceToken;
RefPtr<WebCore::GraphicsSurface> m_graphicsSurface;
IntSize m_graphicsSurfaceSize;
};
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
index 7f10e31bb..94e449345 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
@@ -23,6 +23,7 @@
#include "GraphicsContext.h"
#include "Image.h"
+#include "LengthFunctions.h"
#include "NotImplemented.h"
#include "TextureMapperShaderManager.h"
#include "Timer.h"
@@ -72,7 +73,7 @@ public:
{
GLContextDataMap::iterator it = glContextDataMap().find(context->platformGraphicsContext3D());
if (it != glContextDataMap().end())
- return it->second;
+ return it->value;
return adoptRef(new SharedGLData(context));
}
@@ -92,7 +93,7 @@ public:
GLContextDataMap::const_iterator end = glContextDataMap().end();
GLContextDataMap::iterator it;
for (it = glContextDataMap().begin(); it != end; ++it) {
- if (it->second == this)
+ if (it->value == this)
break;
}
@@ -266,7 +267,7 @@ void TextureMapperGL::endPainting()
void TextureMapperGL::drawQuad(const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram* shaderProgram, GC3Denum drawingMode, bool needsBlending)
{
- m_context3D->enableVertexAttribArray(shaderProgram->vertexAttrib());
+ m_context3D->enableVertexAttribArray(shaderProgram->vertexLocation());
m_context3D->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, 0);
const GC3Dfloat quad[] = {
@@ -275,7 +276,7 @@ void TextureMapperGL::drawQuad(const DrawQuad& quadToDraw, const TransformationM
quadToDraw.targetRectMappedToUnitSquare.p3().x(), quadToDraw.targetRectMappedToUnitSquare.p3().y(),
quadToDraw.targetRectMappedToUnitSquare.p4().x(), quadToDraw.targetRectMappedToUnitSquare.p4().y()
};
- m_context3D->vertexAttribPointer(shaderProgram->vertexAttrib(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(quad));
+ m_context3D->vertexAttribPointer(shaderProgram->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(quad));
TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
quadToDraw.originalTargetRect.width(), 0, 0, 0,
@@ -297,7 +298,7 @@ void TextureMapperGL::drawQuad(const DrawQuad& quadToDraw, const TransformationM
m_context3D->disable(GraphicsContext3D::BLEND);
m_context3D->drawArrays(drawingMode, 0, 4);
- m_context3D->disableVertexAttribArray(shaderProgram->vertexAttrib());
+ m_context3D->disableVertexAttribArray(shaderProgram->vertexLocation());
}
void TextureMapperGL::drawBorder(const Color& color, float width, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix)
@@ -305,15 +306,12 @@ void TextureMapperGL::drawBorder(const Color& color, float width, const FloatRec
if (clipStack().current().scissorBox.isEmpty())
return;
- RefPtr<TextureMapperShaderProgramSolidColor> program = data().sharedGLData().textureMapperShaderManager.solidColorProgram();
- m_context3D->useProgram(program->id());
+ RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::SolidColor);
+ m_context3D->useProgram(program->programID());
- float alpha = color.alpha() / 255.0;
- m_context3D->uniform4f(program->colorLocation(),
- (color.red() / 255.0) * alpha,
- (color.green() / 255.0) * alpha,
- (color.blue() / 255.0) * alpha,
- alpha);
+ float r, g, b, a;
+ color.getRGBA(r, g, b, a);
+ m_context3D->uniform4f(program->colorLocation(), r, g, b, a);
m_context3D->lineWidth(width);
drawQuad(targetRect, modelViewMatrix, program.get(), GraphicsContext3D::LINE_LOOP, color.hasAlpha());
@@ -368,27 +366,25 @@ void TextureMapperGL::drawTextureRectangleARB(uint32_t texture, Flags flags, con
{
RefPtr<TextureMapperShaderProgram> program;
if (maskTexture)
- program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::RectOpacityAndMask);
+ program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::MaskedRect);
else
- program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::RectSimple);
- m_context3D->useProgram(program->id());
+ program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Rect);
+ m_context3D->useProgram(program->programID());
- m_context3D->enableVertexAttribArray(program->vertexAttrib());
+ m_context3D->enableVertexAttribArray(program->vertexLocation());
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
m_context3D->bindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
- m_context3D->uniform1i(program->sourceTextureLocation(), 0);
+ m_context3D->uniform1i(program->samplerLocation(), 0);
m_context3D->uniform1f(program->flipLocation(), !!(flags & ShouldFlipTexture));
m_context3D->uniform2f(program->textureSizeLocation(), textureSize.width(), textureSize.height());
+ m_context3D->uniform1f(program->opacityLocation(), opacity);
- if (TextureMapperShaderProgram::isValidUniformLocation(program->opacityLocation()))
- m_context3D->uniform1f(program->opacityLocation(), opacity);
-
- if (maskTexture && maskTexture->isValid() && TextureMapperShaderProgram::isValidUniformLocation(program->maskTextureLocation())) {
+ if (maskTexture && maskTexture->isValid()) {
const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
m_context3D->activeTexture(GraphicsContext3D::TEXTURE1);
m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureGL->id());
- m_context3D->uniform1i(program->maskTextureLocation(), 1);
+ m_context3D->uniform1i(program->maskLocation(), 1);
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
}
@@ -405,10 +401,10 @@ void TextureMapperGL::drawTexture(uint32_t texture, Flags flags, const IntSize&
RefPtr<TextureMapperShaderProgram> program;
if (maskTexture)
- program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::OpacityAndMask);
+ program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Masked);
else
- program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Simple);
- m_context3D->useProgram(program->id());
+ program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Default);
+ m_context3D->useProgram(program->programID());
drawTexturedQuadWithProgram(program.get(), texture, flags, targetRect, modelViewMatrix, opacity, maskTexture);
}
@@ -536,8 +532,8 @@ bool TextureMapperGL::drawTextureWithAntialiasing(uint32_t texture, Flags flags,
quadToEdgeArray(expandedQuadInScreenSpace, targetQuadEdges);
quadToEdgeArray(inflateQuad(quadInScreenSpace.boundingBox(), inflationDistance), targetQuadEdges + 12);
- RefPtr<TextureMapperShaderProgramAntialiasingNoMask> program = data().sharedGLData().textureMapperShaderManager.antialiasingNoMaskProgram();
- m_context3D->useProgram(program->id());
+ RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Antialiased);
+ m_context3D->useProgram(program->programID());
m_context3D->uniform3fv(program->expandedQuadEdgesInScreenSpaceLocation(), 8, targetQuadEdges);
drawTexturedQuadWithProgram(program.get(), texture, flags, DrawQuad(originalTargetRect, expandedQuadInTextureCoordinates), modelViewMatrix, opacity, 0 /* maskTexture */);
@@ -546,21 +542,19 @@ bool TextureMapperGL::drawTextureWithAntialiasing(uint32_t texture, Flags flags,
void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
{
- m_context3D->enableVertexAttribArray(program->vertexAttrib());
+ m_context3D->enableVertexAttribArray(program->vertexLocation());
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
- m_context3D->uniform1i(program->sourceTextureLocation(), 0);
+ m_context3D->uniform1i(program->samplerLocation(), 0);
m_context3D->uniform1f(program->flipLocation(), !!(flags & ShouldFlipTexture));
+ m_context3D->uniform1f(program->opacityLocation(), opacity);
- if (TextureMapperShaderProgram::isValidUniformLocation(program->opacityLocation()))
- m_context3D->uniform1f(program->opacityLocation(), opacity);
-
- if (maskTexture && maskTexture->isValid() && TextureMapperShaderProgram::isValidUniformLocation(program->maskTextureLocation())) {
+ if (maskTexture && maskTexture->isValid()) {
const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
m_context3D->activeTexture(GraphicsContext3D::TEXTURE1);
m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureGL->id());
- m_context3D->uniform1i(program->maskTextureLocation(), 1);
+ m_context3D->uniform1i(program->maskLocation(), 1);
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
}
@@ -568,6 +562,15 @@ void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* pr
drawQuad(quadToDraw, modelViewMatrix, program, GraphicsContext3D::TRIANGLE_FAN, needsBlending);
}
+BitmapTextureGL::BitmapTextureGL(TextureMapperGL* textureMapper)
+ : m_id(0)
+ , m_fbo(0)
+ , m_rbo(0)
+ , m_shouldClear(true)
+ , m_context3D(textureMapper->graphicsContext3D())
+{
+}
+
bool BitmapTextureGL::canReuseWith(const IntSize& contentsSize, Flags)
{
return contentsSize == m_textureSize;
@@ -611,10 +614,8 @@ static bool driverSupportsSubImage()
void BitmapTextureGL::didReset()
{
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
-
if (!m_id)
- m_id = context3D->createTexture();
+ m_id = m_context3D->createTexture();
m_shouldClear = true;
if (m_textureSize == contentSize())
@@ -623,21 +624,19 @@ void BitmapTextureGL::didReset()
Platform3DObject format = driverSupportsBGRASwizzling() ? GraphicsContext3D::BGRA : GraphicsContext3D::RGBA;
m_textureSize = contentSize();
- context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
- context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
- context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- context3D->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_textureSize.width(), m_textureSize.height(), 0, format, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, 0);
+ m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
+ m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context3D->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_textureSize.width(), m_textureSize.height(), 0, format, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, 0);
}
void BitmapTextureGL::updateContents(const void* data, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine)
{
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
-
Platform3DObject glFormat = GraphicsContext3D::RGBA;
- context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
+ m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, m_id);
const unsigned bytesPerPixel = 4;
if (driverSupportsBGRASwizzling())
@@ -645,8 +644,8 @@ void BitmapTextureGL::updateContents(const void* data, const IntRect& targetRect
else
swizzleBGRAToRGBA(reinterpret_cast<uint32_t*>(const_cast<void*>(data)), IntRect(sourceOffset, targetRect.size()), bytesPerLine / bytesPerPixel);
- if (bytesPerLine == targetRect.width() / 4 && sourceOffset == IntPoint::zero()) {
- context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, (const char*)data);
+ if (bytesPerLine == targetRect.width() * bytesPerPixel && sourceOffset == IntPoint::zero()) {
+ m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, (const char*)data);
return;
}
@@ -664,19 +663,19 @@ void BitmapTextureGL::updateContents(const void* data, const IntRect& targetRect
dst += targetBytesPerLine;
}
- context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, temporaryData.data());
+ m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, temporaryData.data());
return;
}
#if !defined(TEXMAP_OPENGL_ES_2)
// Use the OpenGL sub-image extension, now that we know it's available.
- context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerLine / bytesPerPixel);
- context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, sourceOffset.y());
- context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, sourceOffset.x());
- context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, (const char*)data);
- context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, bytesPerLine / bytesPerPixel);
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, sourceOffset.y());
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, sourceOffset.x());
+ m_context3D->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(), glFormat, DEFAULT_TEXTURE_PIXEL_TRANSFER_TYPE, (const char*)data);
+ m_context3D->pixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ m_context3D->pixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
#endif
}
@@ -692,8 +691,9 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co
const char* imageData;
#if PLATFORM(QT)
- imageData = reinterpret_cast<const char*>(frameImage->constBits());
- bytesPerLine = frameImage->bytesPerLine();
+ QImage qImage = frameImage->toImage();
+ imageData = reinterpret_cast<const char*>(qImage.constBits());
+ bytesPerLine = qImage.bytesPerLine();
#elif USE(CAIRO)
cairo_surface_t* surface = frameImage->surface();
imageData = reinterpret_cast<const char*>(cairo_image_surface_get_data(surface));
@@ -704,48 +704,193 @@ void BitmapTextureGL::updateContents(Image* image, const IntRect& targetRect, co
}
#if ENABLE(CSS_FILTERS)
-void TextureMapperGL::drawFiltered(const BitmapTexture& sourceTexture, const BitmapTexture& contentTexture, const FilterOperation& filter, int pass)
+
+static TextureMapperShaderManager::ShaderKey keyForFilterType(FilterOperation::OperationType type, unsigned pass)
+{
+ switch (type) {
+ case FilterOperation::GRAYSCALE:
+ return TextureMapperShaderManager::GrayscaleFilter;
+ case FilterOperation::SEPIA:
+ return TextureMapperShaderManager::SepiaFilter;
+ case FilterOperation::SATURATE:
+ return TextureMapperShaderManager::SaturateFilter;
+ case FilterOperation::HUE_ROTATE:
+ return TextureMapperShaderManager::HueRotateFilter;
+ case FilterOperation::INVERT:
+ return TextureMapperShaderManager::InvertFilter;
+ case FilterOperation::BRIGHTNESS:
+ return TextureMapperShaderManager::BrightnessFilter;
+ case FilterOperation::CONTRAST:
+ return TextureMapperShaderManager::ContrastFilter;
+ case FilterOperation::OPACITY:
+ return TextureMapperShaderManager::OpacityFilter;
+ case FilterOperation::BLUR:
+ return TextureMapperShaderManager::BlurFilter;
+ case FilterOperation::DROP_SHADOW:
+ return pass ? TextureMapperShaderManager::ShadowFilterPass2 : TextureMapperShaderManager::ShadowFilterPass1;
+ default:
+ ASSERT_NOT_REACHED();
+ return TextureMapperShaderManager::Invalid;
+ }
+}
+
+static unsigned getPassesRequiredForFilter(FilterOperation::OperationType type)
+{
+ switch (type) {
+ case FilterOperation::GRAYSCALE:
+ case FilterOperation::SEPIA:
+ case FilterOperation::SATURATE:
+ case FilterOperation::HUE_ROTATE:
+ case FilterOperation::INVERT:
+ case FilterOperation::BRIGHTNESS:
+ case FilterOperation::CONTRAST:
+ case FilterOperation::OPACITY:
+ return 1;
+ case FilterOperation::BLUR:
+ case FilterOperation::DROP_SHADOW:
+ // We use two-passes (vertical+horizontal) for blur and drop-shadow.
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+// Create a normal distribution of 21 values between -2 and 2.
+static const int GaussianKernelHalfWidth = 11;
+static const float GaussianKernelStep = 0.2;
+
+static inline float gauss(float x)
+{
+ return exp(-(x * x) / 2.);
+}
+
+static float* gaussianKernel()
+{
+ static bool prepared = false;
+ static float kernel[GaussianKernelHalfWidth] = {0, };
+
+ if (prepared)
+ return kernel;
+
+ kernel[0] = gauss(0);
+ float sum = kernel[0];
+ for (unsigned i = 1; i < GaussianKernelHalfWidth; ++i) {
+ kernel[i] = gauss(i * GaussianKernelStep);
+ sum += 2 * kernel[i];
+ }
+
+ // Normalize the kernel.
+ float scale = 1 / sum;
+ for (unsigned i = 0; i < GaussianKernelHalfWidth; ++i)
+ kernel[i] *= scale;
+
+ prepared = true;
+ return kernel;
+}
+
+static void prepareFilterProgram(TextureMapperShaderProgram* program, const FilterOperation& operation, unsigned pass, const IntSize& size, GC3Duint contentTexture)
+{
+ RefPtr<GraphicsContext3D> context = program->context();
+ context->useProgram(program->programID());
+
+ switch (operation.getOperationType()) {
+ case FilterOperation::GRAYSCALE:
+ case FilterOperation::SEPIA:
+ case FilterOperation::SATURATE:
+ case FilterOperation::HUE_ROTATE:
+ context->uniform1f(program->amountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
+ break;
+ case FilterOperation::INVERT:
+ case FilterOperation::BRIGHTNESS:
+ case FilterOperation::CONTRAST:
+ case FilterOperation::OPACITY:
+ context->uniform1f(program->amountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
+ break;
+ case FilterOperation::BLUR: {
+ const BlurFilterOperation& blur = static_cast<const BlurFilterOperation&>(operation);
+ FloatSize radius;
+
+ // Blur is done in two passes, first horizontally and then vertically. The same shader is used for both.
+ if (pass)
+ radius.setHeight(floatValueForLength(blur.stdDeviation(), size.height()) / size.height());
+ else
+ radius.setWidth(floatValueForLength(blur.stdDeviation(), size.width()) / size.width());
+
+ context->uniform2f(program->blurRadiusLocation(), radius.width(), radius.height());
+ context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
+ break;
+ }
+ case FilterOperation::DROP_SHADOW: {
+ const DropShadowFilterOperation& shadow = static_cast<const DropShadowFilterOperation&>(operation);
+ context->uniform1fv(program->gaussianKernelLocation(), GaussianKernelHalfWidth, gaussianKernel());
+ switch (pass) {
+ case 0:
+ // First pass: vertical alpha blur.
+ context->uniform2f(program->shadowOffsetLocation(), float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
+ context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.width()));
+ break;
+ case 1:
+ // Second pass: we need the shadow color and the content texture for compositing.
+ context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.height()));
+ context->activeTexture(GraphicsContext3D::TEXTURE1);
+ context->bindTexture(GraphicsContext3D::TEXTURE_2D, contentTexture);
+ context->uniform1i(program->contentTextureLocation(), 1);
+ float r, g, b, a;
+ shadow.color().getRGBA(r, g, b, a);
+ context->uniform4f(program->shadowColorLocation(), r, g, b, a);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTexture& contentTexture, const FilterOperation& filter, int pass)
{
// For standard filters, we always draw the whole texture without transformations.
- RefPtr<StandardFilterProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderForFilter(filter, pass);
+ TextureMapperShaderManager::ShaderKey key = keyForFilterType(filter.getOperationType(), pass);
+ RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(key);
ASSERT(program);
- program->prepare(filter, pass, sourceTexture.contentSize(), static_cast<const BitmapTextureGL&>(contentTexture).id());
+ prepareFilterProgram(program.get(), filter, pass, sampler.contentSize(), static_cast<const BitmapTextureGL&>(contentTexture).id());
- m_context3D->enableVertexAttribArray(program->vertexAttrib());
- m_context3D->enableVertexAttribArray(program->texCoordAttrib());
+ m_context3D->enableVertexAttribArray(program->vertexLocation());
+ m_context3D->enableVertexAttribArray(program->texCoordLocation());
m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
- m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, static_cast<const BitmapTextureGL&>(sourceTexture).id());
- m_context3D->uniform1i(program->textureUniform(), 0);
+ m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, static_cast<const BitmapTextureGL&>(sampler).id());
+ m_context3D->uniform1i(program->samplerLocation(), 0);
const GC3Dfloat targetVertices[] = {-1, -1, 1, -1, 1, 1, -1, 1};
const GC3Dfloat sourceVertices[] = {0, 0, 1, 0, 1, 1, 0, 1};
- m_context3D->vertexAttribPointer(program->vertexAttrib(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(targetVertices));
- m_context3D->vertexAttribPointer(program->texCoordAttrib(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(sourceVertices));
+ m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(targetVertices));
+ m_context3D->vertexAttribPointer(program->texCoordLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(sourceVertices));
m_context3D->disable(GraphicsContext3D::BLEND);
m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);
- m_context3D->disableVertexAttribArray(program->vertexAttrib());
- m_context3D->disableVertexAttribArray(program->texCoordAttrib());
+ m_context3D->disableVertexAttribArray(program->vertexLocation());
+ m_context3D->disableVertexAttribArray(program->texCoordLocation());
}
-PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(const BitmapTexture& contentTexture, const FilterOperations& filters)
+PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper* textureMapper, const BitmapTexture& contentTexture, const FilterOperations& filters)
{
- RefPtr<BitmapTexture> previousSurface = m_textureMapper->data().currentSurface;
+ TextureMapperGL* textureMapperGL = static_cast<TextureMapperGL*>(textureMapper);
+ RefPtr<BitmapTexture> previousSurface = textureMapperGL->data().currentSurface;
RefPtr<BitmapTexture> source = this;
- RefPtr<BitmapTexture> target = m_textureMapper->acquireTextureFromPool(m_textureSize);
- for (int i = 0; i < filters.size(); ++i) {
+ RefPtr<BitmapTexture> target = textureMapper->acquireTextureFromPool(m_textureSize);
+ for (size_t i = 0; i < filters.size(); ++i) {
const FilterOperation* filter = filters.at(i);
ASSERT(filter);
- int numPasses = m_textureMapper->data().sharedGLData().textureMapperShaderManager.getPassesRequiredForFilter(*filter);
+ int numPasses = getPassesRequiredForFilter(filter->getOperationType());
for (int j = 0; j < numPasses; ++j) {
- m_textureMapper->bindSurface(target.get());
- m_textureMapper->drawFiltered((i || j) ? *source : contentTexture, contentTexture, *filter, j);
+ textureMapperGL->bindSurface(target.get());
+ textureMapperGL->drawFiltered((i || j) ? *source : contentTexture, contentTexture, *filter, j);
std::swap(source, target);
}
}
- m_textureMapper->bindSurface(previousSurface.get());
+ textureMapperGL->bindSurface(previousSurface.get());
return source;
}
#endif
@@ -766,18 +911,17 @@ void BitmapTextureGL::initializeStencil()
if (m_rbo)
return;
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
- m_rbo = context3D->createRenderbuffer();
- context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_rbo);
+ m_rbo = m_context3D->createRenderbuffer();
+ m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_rbo);
#ifdef TEXMAP_OPENGL_ES_2
- context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, m_textureSize.width(), m_textureSize.height());
+ m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::STENCIL_INDEX8, m_textureSize.width(), m_textureSize.height());
#else
- context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_STENCIL, m_textureSize.width(), m_textureSize.height());
+ m_context3D->renderbufferStorage(GraphicsContext3D::RENDERBUFFER, GraphicsContext3D::DEPTH_STENCIL, m_textureSize.width(), m_textureSize.height());
#endif
- context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
- context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_rbo);
- context3D->clearStencil(0);
- context3D->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
+ m_context3D->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, 0);
+ m_context3D->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::RENDERBUFFER, m_rbo);
+ m_context3D->clearStencil(0);
+ m_context3D->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
}
void BitmapTextureGL::clearIfNeeded()
@@ -785,12 +929,10 @@ void BitmapTextureGL::clearIfNeeded()
if (!m_shouldClear)
return;
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
-
m_clipStack.init(IntRect(IntPoint::zero(), m_textureSize));
- m_clipStack.apply(context3D);
- context3D->clearColor(0, 0, 0, 0);
- context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ m_clipStack.apply(m_context3D.get());
+ m_context3D->clearColor(0, 0, 0, 0);
+ m_context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
m_shouldClear = false;
}
@@ -799,37 +941,33 @@ void BitmapTextureGL::createFboIfNeeded()
if (m_fbo)
return;
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
- m_fbo = context3D->createFramebuffer();
- context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- context3D->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, id(), 0);
+ m_fbo = m_context3D->createFramebuffer();
+ m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+ m_context3D->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, id(), 0);
m_shouldClear = true;
}
-void BitmapTextureGL::bind()
+void BitmapTextureGL::bind(TextureMapperGL* textureMapper)
{
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
- context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
+ m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
createFboIfNeeded();
- context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
- context3D->viewport(0, 0, m_textureSize.width(), m_textureSize.height());
+ m_context3D->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+ m_context3D->viewport(0, 0, m_textureSize.width(), m_textureSize.height());
clearIfNeeded();
- m_textureMapper->data().projectionMatrix = createProjectionMatrix(m_textureSize, true /* mirrored */);
- m_clipStack.apply(context3D);
+ textureMapper->data().projectionMatrix = createProjectionMatrix(m_textureSize, true /* mirrored */);
+ m_clipStack.apply(m_context3D.get());
}
BitmapTextureGL::~BitmapTextureGL()
{
- GraphicsContext3D* context3D = m_textureMapper->graphicsContext3D();
-
if (m_id)
- context3D->deleteTexture(m_id);
+ m_context3D->deleteTexture(m_id);
if (m_fbo)
- context3D->deleteFramebuffer(m_fbo);
+ m_context3D->deleteFramebuffer(m_fbo);
if (m_rbo)
- context3D->deleteRenderbuffer(m_rbo);
+ m_context3D->deleteRenderbuffer(m_rbo);
}
bool BitmapTextureGL::isValid() const
@@ -864,7 +1002,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surface)
return;
}
- static_cast<BitmapTextureGL*>(surface)->bind();
+ static_cast<BitmapTextureGL*>(surface)->bind(this);
data().currentSurface = surface;
}
@@ -895,12 +1033,12 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con
data().initializeStencil();
- RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Simple);
+ RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Default);
- m_context3D->useProgram(program->id());
- m_context3D->enableVertexAttribArray(program->vertexAttrib());
+ m_context3D->useProgram(program->programID());
+ m_context3D->enableVertexAttribArray(program->vertexLocation());
const GC3Dfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
- m_context3D->vertexAttribPointer(program->vertexAttrib(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(unitRect));
+ m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(unitRect));
TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix)
.multiply(modelViewMatrix)
@@ -944,7 +1082,7 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con
m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);
// Clear the state.
- m_context3D->disableVertexAttribArray(program->vertexAttrib());
+ m_context3D->disableVertexAttribArray(program->vertexLocation());
m_context3D->stencilMask(0);
// Increase stencilIndex and apply stencil testing.
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
index 8a72d67af..64bffafe5 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
@@ -133,19 +133,18 @@ public:
virtual bool isValid() const;
virtual bool canReuseWith(const IntSize& contentsSize, Flags = 0);
virtual void didReset();
- void bind();
+ void bind(TextureMapperGL*);
void initializeStencil();
~BitmapTextureGL();
virtual uint32_t id() const { return m_id; }
uint32_t textureTarget() const { return GraphicsContext3D::TEXTURE_2D; }
IntSize textureSize() const { return m_textureSize; }
- void setTextureMapper(TextureMapperGL* texmap) { m_textureMapper = texmap; }
void updateContents(Image*, const IntRect&, const IntPoint&);
virtual void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine);
virtual bool isBackedByOpenGL() const { return true; }
#if ENABLE(CSS_FILTERS)
- virtual PassRefPtr<BitmapTexture> applyFilters(const BitmapTexture& contentTexture, const FilterOperations&);
+ virtual PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const BitmapTexture& contentTexture, const FilterOperations&);
#endif
private:
@@ -156,17 +155,10 @@ private:
Platform3DObject m_rbo;
bool m_shouldClear;
TextureMapperGL::ClipStack m_clipStack;
- TextureMapperGL* m_textureMapper;
+ RefPtr<GraphicsContext3D> m_context3D;
+ BitmapTextureGL(TextureMapperGL*);
BitmapTextureGL();
- BitmapTextureGL(TextureMapperGL* textureMapper)
- : m_id(0)
- , m_fbo(0)
- , m_rbo(0)
- , m_shouldClear(true)
- , m_textureMapper(textureMapper)
- {
- }
void clearIfNeeded();
void createFboIfNeeded();
@@ -174,8 +166,6 @@ private:
friend class TextureMapperGL;
};
-typedef uint64_t ImageUID;
-ImageUID uidForImage(Image*);
BitmapTextureGL* toBitmapTextureGL(BitmapTexture*);
}
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
index 9b0c9a56f..9282959de 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
@@ -121,7 +121,7 @@ void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const F
}
#if ENABLE(CSS_FILTERS)
-PassRefPtr<BitmapTexture> BitmapTextureImageBuffer::applyFilters(const BitmapTexture& contentTexture, const FilterOperations& filters)
+PassRefPtr<BitmapTexture> BitmapTextureImageBuffer::applyFilters(TextureMapper*, const BitmapTexture& contentTexture, const FilterOperations& filters)
{
RefPtr<FilterEffectRenderer> renderer = FilterEffectRenderer::create();
renderer->setSourceImageRect(FloatRect(FloatPoint::zero(), contentTexture.size()));
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
index 71511fc12..7d51e8805 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
@@ -37,7 +37,7 @@ public:
virtual void updateContents(Image*, const IntRect&, const IntPoint&);
virtual void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine);
#if ENABLE(CSS_FILTERS)
- PassRefPtr<BitmapTexture> applyFilters(const BitmapTexture&, const FilterOperations&);
+ PassRefPtr<BitmapTexture> applyFilters(TextureMapper*, const BitmapTexture&, const FilterOperations&);
#endif
private:
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
index 36958987d..e36dbc948 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
@@ -342,7 +342,7 @@ static PassRefPtr<BitmapTexture> applyFilters(const FilterOperations& filters, T
return source;
RefPtr<BitmapTexture> filterSurface = shouldKeepContentTexture(filters) ? textureMapper->acquireTextureFromPool(source->size()) : source;
- return filterSurface->applyFilters(*source, filters);
+ return filterSurface->applyFilters(textureMapper, *source, filters);
}
#endif
@@ -402,12 +402,12 @@ TextureMapperLayer::~TextureMapperLayer()
m_parent->m_children.remove(m_parent->m_children.find(this));
}
-void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, int options)
+void TextureMapperLayer::flushCompositingState(GraphicsLayerTextureMapper* graphicsLayer, int options)
{
- syncCompositingState(graphicsLayer, rootLayer()->m_textureMapper, options);
+ flushCompositingState(graphicsLayer, rootLayer()->m_textureMapper, options);
}
-void TextureMapperLayer::syncCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper)
+void TextureMapperLayer::flushCompositingStateSelf(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper)
{
int changeMask = graphicsLayer->changeMask();
@@ -519,18 +519,18 @@ void TextureMapperLayer::syncAnimations()
setOpacity(m_state.opacity);
}
-void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper, int options)
+void TextureMapperLayer::flushCompositingState(GraphicsLayerTextureMapper* graphicsLayer, TextureMapper* textureMapper, int options)
{
if (!textureMapper)
return;
if (graphicsLayer && !(options & ComputationsOnly)) {
- syncCompositingStateSelf(graphicsLayer, textureMapper);
+ flushCompositingStateSelf(graphicsLayer, textureMapper);
graphicsLayer->didSynchronize();
}
if (graphicsLayer && m_state.maskLayer) {
- m_state.maskLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), textureMapper);
+ m_state.maskLayer->flushCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->maskLayer()), textureMapper);
// A mask layer has its parent's size by default, in case it's not set specifically.
if (m_state.maskLayer->m_size.isEmpty())
@@ -538,7 +538,7 @@ void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphi
}
if (m_state.replicaLayer)
- m_state.replicaLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), textureMapper);
+ m_state.replicaLayer->flushCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), textureMapper);
syncAnimations();
updateBackingStore(textureMapper, graphicsLayer);
@@ -552,11 +552,11 @@ void TextureMapperLayer::syncCompositingState(GraphicsLayerTextureMapper* graphi
TextureMapperLayer* layer = toTextureMapperLayer(children[i]);
if (!layer)
continue;
- layer->syncCompositingState(toGraphicsLayerTextureMapper(children[i]), textureMapper, options);
+ layer->flushCompositingState(toGraphicsLayerTextureMapper(children[i]), textureMapper, options);
}
} else {
for (int i = m_children.size() - 1; i >= 0; --i)
- m_children[i]->syncCompositingState(0, textureMapper, options);
+ m_children[i]->flushCompositingState(0, textureMapper, options);
}
}
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
index 2f7f4b821..5740acf52 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
@@ -114,8 +114,8 @@ public:
virtual ~TextureMapperLayer();
- void syncCompositingState(GraphicsLayerTextureMapper*, int syncOptions = 0);
- void syncCompositingState(GraphicsLayerTextureMapper*, TextureMapper*, int syncOptions = 0);
+ void flushCompositingState(GraphicsLayerTextureMapper*, int syncOptions = 0);
+ void flushCompositingState(GraphicsLayerTextureMapper*, TextureMapper*, int syncOptions = 0);
IntSize size() const { return IntSize(m_size.width(), m_size.height()); }
void setTransform(const TransformationMatrix&);
void setOpacity(float value) { m_opacity = value; }
@@ -144,7 +144,7 @@ private:
FloatRect targetRectForTileRect(const FloatRect& totalTargetRect, const FloatRect& tileRect) const;
void invalidateViewport(const FloatRect&);
void notifyChange(ChangeMask);
- void syncCompositingStateSelf(GraphicsLayerTextureMapper*, TextureMapper*);
+ void flushCompositingStateSelf(GraphicsLayerTextureMapper*, TextureMapper*);
static int compareGraphicsLayersZValue(const void* a, const void* b);
static void sortByZOrder(Vector<TextureMapperLayer* >& array, int first, int last);
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h b/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
index 2292f4eb4..db3f0bec6 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
@@ -20,6 +20,10 @@
#ifndef TextureMapperPlatformLayer_h
#define TextureMapperPlatformLayer_h
+#if USE(GRAPHICS_SURFACE)
+#include "GraphicsSurface.h"
+#endif
+
#include "TransformationMatrix.h"
namespace WebCore {
@@ -34,7 +38,7 @@ public:
virtual void swapBuffers() { }
#if USE(GRAPHICS_SURFACE)
virtual uint32_t copyToGraphicsSurface() { return 0; }
- virtual uint64_t graphicsSurfaceToken() const { return 0; }
+ virtual GraphicsSurfaceToken graphicsSurfaceToken() const { return GraphicsSurfaceToken(); }
#endif
};
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
index 73d6fefbb..27e786713 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp
@@ -28,249 +28,69 @@
#include "Logging.h"
#include "TextureMapperGL.h"
+#define STRINGIFY(...) #__VA_ARGS__
+
namespace WebCore {
-#define STRINGIFY(...) #__VA_ARGS__
-static const char* fragmentShaderSourceOpacityAndMask =
- STRINGIFY(
- precision mediump float;
- uniform sampler2D s_source;
- uniform sampler2D s_mask;
- uniform lowp float u_opacity;
- varying highp vec2 v_sourceTexCoord;
- varying highp vec2 v_maskTexCoord;
- void main(void)
- {
- lowp vec4 color = texture2D(s_source, v_sourceTexCoord);
- lowp vec4 maskColor = texture2D(s_mask, v_maskTexCoord);
- lowp float fragmentAlpha = u_opacity * maskColor.a;
- gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
- }
- );
-
-static const char* fragmentShaderSourceRectOpacityAndMask =
- STRINGIFY(
- precision mediump float;
- uniform sampler2DRect s_source;
- uniform sampler2DRect s_mask;
- uniform lowp float u_opacity;
- varying highp vec2 v_sourceTexCoord;
- varying highp vec2 v_maskTexCoord;
- void main(void)
- {
- lowp vec4 color = texture2DRect(s_source, v_sourceTexCoord);
- lowp vec4 maskColor = texture2DRect(s_mask, v_maskTexCoord);
- lowp float fragmentAlpha = u_opacity * maskColor.a;
- gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
- }
- );
-
-static const char* vertexShaderSourceOpacityAndMask =
- STRINGIFY(
- uniform mat4 u_matrix;
- uniform lowp float u_flip;
- attribute vec4 a_vertex;
- varying highp vec2 v_sourceTexCoord;
- varying highp vec2 v_maskTexCoord;
- void main(void)
- {
- v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip));
- v_maskTexCoord = vec2(a_vertex);
- gl_Position = u_matrix * a_vertex;
- }
- );
-
-static const char* fragmentShaderSourceSimple =
- STRINGIFY(
- precision mediump float;
- uniform sampler2D s_source;
- uniform lowp float u_opacity;
- varying highp vec2 v_sourceTexCoord;
- void main(void)
- {
- lowp vec4 color = texture2D(s_source, v_sourceTexCoord);
- gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
- }
- );
-
-static const char* fragmentShaderSourceAntialiasingNoMask =
- STRINGIFY(
- precision mediump float;
- uniform sampler2D s_source;
- varying highp vec2 v_sourceTexCoord;
- uniform lowp float u_opacity;
- uniform vec3 u_expandedQuadEdgesInScreenSpace[8];
- void main()
- {
- vec4 sampledColor = texture2D(s_source, clamp(v_sourceTexCoord, 0.0, 1.0));
- vec3 pos = vec3(gl_FragCoord.xy, 1);
-
- // The data passed in u_expandedQuadEdgesInScreenSpace is merely the
- // pre-scaled coeffecients of the line equations describing the four edges
- // of the expanded quad in screen space and the rectangular bounding box
- // of the expanded quad.
- //
- // We are doing a simple distance calculation here according to the formula:
- // (A*p.x + B*p.y + C) / sqrt(A^2 + B^2) = distance from line to p
- // Note that A, B and C have already been scaled by 1 / sqrt(A^2 + B^2).
- float a0 = clamp(dot(u_expandedQuadEdgesInScreenSpace[0], pos), 0.0, 1.0);
- float a1 = clamp(dot(u_expandedQuadEdgesInScreenSpace[1], pos), 0.0, 1.0);
- float a2 = clamp(dot(u_expandedQuadEdgesInScreenSpace[2], pos), 0.0, 1.0);
- float a3 = clamp(dot(u_expandedQuadEdgesInScreenSpace[3], pos), 0.0, 1.0);
- float a4 = clamp(dot(u_expandedQuadEdgesInScreenSpace[4], pos), 0.0, 1.0);
- float a5 = clamp(dot(u_expandedQuadEdgesInScreenSpace[5], pos), 0.0, 1.0);
- float a6 = clamp(dot(u_expandedQuadEdgesInScreenSpace[6], pos), 0.0, 1.0);
- float a7 = clamp(dot(u_expandedQuadEdgesInScreenSpace[7], pos), 0.0, 1.0);
-
- // Now we want to reduce the alpha value of the fragment if it is close to the
- // edges of the expanded quad (or rectangular bounding box -- which seems to be
- // important for backfacing quads). Note that we are combining the contribution
- // from the (top || bottom) and (left || right) edge by simply multiplying. This follows
- // the approach described at: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html,
- // in this case without using Gaussian weights.
- gl_FragColor = sampledColor * u_opacity * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
- }
- );
-
-static const char* fragmentShaderSourceRectSimple =
- STRINGIFY(
- precision mediump float;
- uniform sampler2DRect s_source;
- uniform lowp vec2 u_textureSize;
- uniform lowp float u_opacity;
- varying highp vec2 v_sourceTexCoord;
- void main(void)
- {
- lowp vec4 color = texture2DRect(s_source, u_textureSize * v_sourceTexCoord);
- gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
- }
- );
-
-static const char* vertexShaderSourceSimple =
- STRINGIFY(
- uniform mat4 u_matrix;
- uniform lowp float u_flip;
- attribute vec4 a_vertex;
- varying highp vec2 v_sourceTexCoord;
- void main(void)
- {
- v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip));
- gl_Position = u_matrix * a_vertex;
- }
- );
-
-static const char* vertexShaderSourceSolidColor =
- STRINGIFY(
- uniform mat4 u_matrix;
- attribute vec4 a_vertex;
- void main(void)
- {
- gl_Position = u_matrix * a_vertex;
- }
- );
-
-
-static const char* fragmentShaderSourceSolidColor =
- STRINGIFY(
- precision mediump float;
- uniform vec4 u_color;
- void main(void)
- {
- gl_FragColor = u_color;
- }
- );
-
-PassRefPtr<TextureMapperShaderProgramSolidColor> TextureMapperShaderManager::solidColorProgram()
+static inline bool compositingLogEnabled()
{
- return static_pointer_cast<TextureMapperShaderProgramSolidColor>(getShaderProgram(SolidColor));
+#if !LOG_DISABLED
+ return LogCompositing.state == WTFLogChannelOn;
+#else
+ return false;
+#endif
}
-PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> TextureMapperShaderManager::antialiasingNoMaskProgram()
+TextureMapperShaderProgram::TextureMapperShaderProgram(PassRefPtr<GraphicsContext3D> context, const String& vertex, const String& fragment)
+ : m_context(context)
{
- return static_pointer_cast<TextureMapperShaderProgramAntialiasingNoMask>(getShaderProgram(AntialiasingNoMask));
+ m_vertexShader = m_context->createShader(GraphicsContext3D::VERTEX_SHADER);
+ m_fragmentShader = m_context->createShader(GraphicsContext3D::FRAGMENT_SHADER);
+ m_context->shaderSource(m_vertexShader, vertex);
+ m_context->shaderSource(m_fragmentShader, fragment);
+ m_id = m_context->createProgram();
+ m_context->compileShader(m_vertexShader);
+ m_context->compileShader(m_fragmentShader);
+ m_context->attachShader(m_id, m_vertexShader);
+ m_context->attachShader(m_id, m_fragmentShader);
+ m_context->linkProgram(m_id);
+
+ if (!compositingLogEnabled())
+ return;
+
+ if (m_context->getError() == GraphicsContext3D::NO_ERROR)
+ return;
+
+ String log = m_context->getShaderInfoLog(m_vertexShader);
+ LOG(Compositing, "Vertex shader log: %s\n", log.utf8().data());
+ log = m_context->getShaderInfoLog(m_fragmentShader);
+ LOG(Compositing, "Fragment shader log: %s\n", log.utf8().data());
+ log = m_context->getProgramInfoLog(m_id);
+ LOG(Compositing, "Program log: %s\n", log.utf8().data());
}
-PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProgram(ShaderType shaderType)
+GC3Duint TextureMapperShaderProgram::getLocation(const AtomicString& name, VariableType type)
{
- RefPtr<TextureMapperShaderProgram> program;
- if (shaderType == Invalid)
- return program;
+ HashMap<AtomicString, GC3Duint>::iterator it = m_variables.find(name);
+ if (it != m_variables.end())
+ return it->value;
- TextureMapperShaderProgramMap::iterator it = m_textureMapperShaderProgramMap.find(shaderType);
- if (it != m_textureMapperShaderProgramMap.end())
- return it->second;
-
- switch (shaderType) {
- case Simple:
- program = TextureMapperShaderProgramSimple::create(m_context);
- break;
- case RectSimple:
- program = TextureMapperShaderProgramRectSimple::create(m_context);
- break;
- case AntialiasingNoMask:
- program = TextureMapperShaderProgramAntialiasingNoMask::create(m_context);
- break;
- case OpacityAndMask:
- program = TextureMapperShaderProgramOpacityAndMask::create(m_context);
- break;
- case RectOpacityAndMask:
- program = TextureMapperShaderProgramRectOpacityAndMask::create(m_context);
+ GC3Duint location = 0;
+ switch (type) {
+ case UniformVariable:
+ location = m_context->getUniformLocation(m_id, name);
break;
- case SolidColor:
- program = TextureMapperShaderProgramSolidColor::create(m_context);
+ case AttribVariable:
+ location = m_context->getAttribLocation(m_id, name);
break;
- case Invalid:
+ default:
ASSERT_NOT_REACHED();
+ break;
}
- m_textureMapperShaderProgramMap.add(shaderType, program);
- return program;
-}
-
-TextureMapperShaderProgram::TextureMapperShaderProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource)
- : m_context(context)
- , m_id(0)
- , m_vertexAttrib(0)
- , m_vertexShader(0)
- , m_fragmentShader(0)
- , m_matrixLocation(-1)
- , m_flipLocation(-1)
- , m_textureSizeLocation(-1)
- , m_sourceTextureLocation(-1)
- , m_opacityLocation(-1)
- , m_maskTextureLocation(-1)
- , m_vertexShaderSource(vertexShaderSource)
- , m_fragmentShaderSource(fragmentShaderSource)
-{
-}
-
-void TextureMapperShaderProgram::initializeProgram()
-{
- const char* vertexShaderSourceProgram = vertexShaderSource();
- const char* fragmentShaderSourceProgram = fragmentShaderSource();
- Platform3DObject vertexShader = m_context->createShader(GraphicsContext3D::VERTEX_SHADER);
- Platform3DObject fragmentShader = m_context->createShader(GraphicsContext3D::FRAGMENT_SHADER);
- m_context->shaderSource(vertexShader, vertexShaderSourceProgram);
- m_context->shaderSource(fragmentShader, fragmentShaderSourceProgram);
- Platform3DObject programID = m_context->createProgram();
- m_context->compileShader(vertexShader);
- m_context->compileShader(fragmentShader);
-
- m_context->attachShader(programID, vertexShader);
- m_context->attachShader(programID, fragmentShader);
- m_context->linkProgram(programID);
-
- m_vertexAttrib = m_context->getAttribLocation(programID, "a_vertex");
-
- m_id = programID;
- m_vertexShader = vertexShader;
- m_fragmentShader = fragmentShader;
-}
-void TextureMapperShaderProgram::getUniformLocation(GC3Dint &variable, const char* name)
-{
- variable = m_context->getUniformLocation(m_id, name);
- ASSERT(variable >= 0);
+ m_variables.add(name, location);
+ return location;
}
TextureMapperShaderProgram::~TextureMapperShaderProgram()
@@ -286,120 +106,189 @@ TextureMapperShaderProgram::~TextureMapperShaderProgram()
m_context->deleteProgram(programID);
}
-TextureMapperShaderProgramSimple::TextureMapperShaderProgramSimple(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceSimple, fragmentShaderSourceSimple)
-{
- initializeProgram();
- getUniformLocation(m_flipLocation, "u_flip");
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_sourceTextureLocation, "s_source");
- getUniformLocation(m_opacityLocation, "u_opacity");
-}
+struct ShaderSpec {
+ String vertexShader;
+ String fragmentShader;
+ ShaderSpec(const char* vertex = 0, const char* fragment = 0)
+ : vertexShader(vertex ? String(ASCIILiteral(vertex)) : String())
+ , fragmentShader(fragment ? String(ASCIILiteral(fragment)) : String())
+ {
+ }
+};
-TextureMapperShaderProgramSolidColor::TextureMapperShaderProgramSolidColor(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceSolidColor, fragmentShaderSourceSolidColor)
+static void getShaderSpec(TextureMapperShaderManager::ShaderKey key, String& vertexSource, String& fragmentSource)
{
- initializeProgram();
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_colorLocation, "u_color");
-}
+ static Vector<ShaderSpec> specs = Vector<ShaderSpec>();
+ static const char* fragmentOpacityAndMask =
+ STRINGIFY(
+ precision mediump float;
+ uniform sampler2D s_sampler;
+ uniform sampler2D s_mask;
+ uniform lowp float u_opacity;
+ varying highp vec2 v_sourceTexCoord;
+ varying highp vec2 v_maskTexCoord;
+ void main(void)
+ {
+ lowp vec4 color = texture2D(s_sampler, v_sourceTexCoord);
+ lowp vec4 maskColor = texture2D(s_mask, v_maskTexCoord);
+ lowp float fragmentAlpha = u_opacity * maskColor.a;
+ gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
+ }
+ );
-TextureMapperShaderProgramRectSimple::TextureMapperShaderProgramRectSimple(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceSimple, fragmentShaderSourceRectSimple)
-{
- initializeProgram();
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_flipLocation, "u_flip");
- getUniformLocation(m_textureSizeLocation, "u_textureSize");
- getUniformLocation(m_sourceTextureLocation, "s_source");
- getUniformLocation(m_opacityLocation, "u_opacity");
-}
+ static const char* fragmentRectOpacityAndMask =
+ STRINGIFY(
+ precision mediump float;
+ uniform sampler2DRect s_sampler;
+ uniform sampler2DRect s_mask;
+ uniform lowp float u_opacity;
+ varying highp vec2 v_sourceTexCoord;
+ varying highp vec2 v_maskTexCoord;
+ void main(void)
+ {
+ lowp vec4 color = texture2DRect(s_sampler, v_sourceTexCoord);
+ lowp vec4 maskColor = texture2DRect(s_mask, v_maskTexCoord);
+ lowp float fragmentAlpha = u_opacity * maskColor.a;
+ gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
+ }
+ );
-TextureMapperShaderProgramOpacityAndMask::TextureMapperShaderProgramOpacityAndMask(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceOpacityAndMask, fragmentShaderSourceOpacityAndMask)
-{
- initializeProgram();
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_flipLocation, "u_flip");
- getUniformLocation(m_sourceTextureLocation, "s_source");
- getUniformLocation(m_maskTextureLocation, "s_mask");
- getUniformLocation(m_opacityLocation, "u_opacity");
-}
+ static const char* vertexOpacityAndMask =
+ STRINGIFY(
+ uniform mat4 u_matrix;
+ uniform lowp float u_flip;
+ attribute vec4 a_vertex;
+ varying highp vec2 v_sourceTexCoord;
+ varying highp vec2 v_maskTexCoord;
+ void main(void)
+ {
+ v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip));
+ v_maskTexCoord = vec2(a_vertex);
+ gl_Position = u_matrix * a_vertex;
+ }
+ );
-TextureMapperShaderProgramRectOpacityAndMask::TextureMapperShaderProgramRectOpacityAndMask(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceOpacityAndMask, fragmentShaderSourceRectOpacityAndMask)
-{
- initializeProgram();
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_flipLocation, "u_flip");
- getUniformLocation(m_sourceTextureLocation, "s_source");
- getUniformLocation(m_maskTextureLocation, "s_mask");
- getUniformLocation(m_opacityLocation, "u_opacity");
-}
+ static const char* fragmentSimple =
+ STRINGIFY(
+ precision mediump float;
+ uniform sampler2D s_sampler;
+ uniform lowp float u_opacity;
+ varying highp vec2 v_sourceTexCoord;
+ void main(void)
+ {
+ lowp vec4 color = texture2D(s_sampler, v_sourceTexCoord);
+ gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
+ }
+ );
-TextureMapperShaderProgramAntialiasingNoMask::TextureMapperShaderProgramAntialiasingNoMask(GraphicsContext3D* context)
- : TextureMapperShaderProgram(context, vertexShaderSourceSimple, fragmentShaderSourceAntialiasingNoMask)
-{
- initializeProgram();
- getUniformLocation(m_matrixLocation, "u_matrix");
- getUniformLocation(m_sourceTextureLocation, "s_source");
- getUniformLocation(m_opacityLocation, "u_opacity");
- getUniformLocation(m_expandedQuadEdgesInScreenSpaceLocation, "u_expandedQuadEdgesInScreenSpace");
- getUniformLocation(m_flipLocation, "u_flip");
-}
+ static const char* fragmentAntialiasingNoMask =
+ STRINGIFY(
+ precision mediump float;
+ uniform sampler2D s_sampler;
+ varying highp vec2 v_sourceTexCoord;
+ uniform lowp float u_opacity;
+ uniform vec3 u_expandedQuadEdgesInScreenSpace[8];
+ void main()
+ {
+ vec4 sampledColor = texture2D(s_sampler, clamp(v_sourceTexCoord, 0.0, 1.0));
+ vec3 pos = vec3(gl_FragCoord.xy, 1);
+
+ // The data passed in u_expandedQuadEdgesInScreenSpace is merely the
+ // pre-scaled coeffecients of the line equations describing the four edges
+ // of the expanded quad in screen space and the rectangular bounding box
+ // of the expanded quad.
+ //
+ // We are doing a simple distance calculation here according to the formula:
+ // (A*p.x + B*p.y + C) / sqrt(A^2 + B^2) = distance from line to p
+ // Note that A, B and C have already been scaled by 1 / sqrt(A^2 + B^2).
+ float a0 = clamp(dot(u_expandedQuadEdgesInScreenSpace[0], pos), 0.0, 1.0);
+ float a1 = clamp(dot(u_expandedQuadEdgesInScreenSpace[1], pos), 0.0, 1.0);
+ float a2 = clamp(dot(u_expandedQuadEdgesInScreenSpace[2], pos), 0.0, 1.0);
+ float a3 = clamp(dot(u_expandedQuadEdgesInScreenSpace[3], pos), 0.0, 1.0);
+ float a4 = clamp(dot(u_expandedQuadEdgesInScreenSpace[4], pos), 0.0, 1.0);
+ float a5 = clamp(dot(u_expandedQuadEdgesInScreenSpace[5], pos), 0.0, 1.0);
+ float a6 = clamp(dot(u_expandedQuadEdgesInScreenSpace[6], pos), 0.0, 1.0);
+ float a7 = clamp(dot(u_expandedQuadEdgesInScreenSpace[7], pos), 0.0, 1.0);
+
+ // Now we want to reduce the alpha value of the fragment if it is close to the
+ // edges of the expanded quad (or rectangular bounding box -- which seems to be
+ // important for backfacing quads). Note that we are combining the contribution
+ // from the (top || bottom) and (left || right) edge by simply multiplying. This follows
+ // the approach described at: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html,
+ // in this case without using Gaussian weights.
+ gl_FragColor = sampledColor * u_opacity * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
+ }
+ );
-TextureMapperShaderManager::TextureMapperShaderManager(GraphicsContext3D* context)
- : m_context(context)
-{
-}
+ static const char* fragmentRectSimple =
+ STRINGIFY(
+ precision mediump float;
+ uniform sampler2DRect s_sampler;
+ uniform lowp vec2 s_samplerSize;
+ uniform lowp float u_opacity;
+ varying highp vec2 v_sourceTexCoord;
+ void main(void)
+ {
+ lowp vec4 color = texture2DRect(s_sampler, s_samplerSize * v_sourceTexCoord);
+ gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
+ }
+ );
-TextureMapperShaderManager::~TextureMapperShaderManager()
-{
-}
+ static const char* vertexSimple =
+ STRINGIFY(
+ uniform mat4 u_matrix;
+ uniform lowp float u_flip;
+ attribute vec4 a_vertex;
+ varying highp vec2 v_sourceTexCoord;
+ void main(void)
+ {
+ v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip));
+ gl_Position = u_matrix * a_vertex;
+ }
+ );
-#if ENABLE(CSS_FILTERS)
+ static const char* vertexSolidColor =
+ STRINGIFY(
+ uniform mat4 u_matrix;
+ attribute vec4 a_vertex;
+ void main(void)
+ {
+ gl_Position = u_matrix * a_vertex;
+ }
+ );
-// Create a normal distribution of 21 values between -2 and 2.
-#define GAUSSIAN_KERNEL_HALF_WIDTH 11
-#define GAUSSIAN_KERNEL_STEP 0.2
-StandardFilterProgram::~StandardFilterProgram()
-{
- m_context->detachShader(m_id, m_vertexShader);
- m_context->deleteShader(m_vertexShader);
- m_context->detachShader(m_id, m_fragmentShader);
- m_context->deleteShader(m_fragmentShader);
- m_context->deleteProgram(m_id);
-}
+ static const char* fragmentSolidColor =
+ STRINGIFY(
+ precision mediump float;
+ uniform vec4 u_color;
+ void main(void)
+ {
+ gl_FragColor = u_color;
+ }
+ );
-StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterOperation::OperationType type, unsigned pass)
- : m_context(context)
- , m_id(0)
-{
- const char* vertexShaderSource =
- STRINGIFY(
- attribute vec4 a_vertex;
- attribute vec4 a_texCoord;
- varying highp vec2 v_texCoord;
- void main(void)
- {
- v_texCoord = vec2(a_texCoord);
- gl_Position = a_vertex;
- }
- );
+ static const char* vertexFilter =
+ STRINGIFY(
+ attribute vec4 a_vertex;
+ attribute vec4 a_texCoord;
+ varying highp vec2 v_texCoord;
+ void main(void)
+ {
+ v_texCoord = vec2(a_texCoord);
+ gl_Position = a_vertex;
+ }
+ );
#define STANDARD_FILTER(...) \
"precision mediump float;\n"\
"varying highp vec2 v_texCoord;\n"\
"uniform highp float u_amount;\n"\
- "uniform sampler2D u_texture;\n"\
- #__VA_ARGS__ \
- "void main(void)\n { gl_FragColor = shade(texture2D(u_texture, v_texCoord)); }"
+ "uniform sampler2D s_sampler;\n"#__VA_ARGS__ \
+ "void main(void)\n { gl_FragColor = shade(texture2D(s_sampler, v_texCoord)); }"
- const char* fragmentShaderSource = 0;
- switch (type) {
- case FilterOperation::GRAYSCALE:
- fragmentShaderSource = STANDARD_FILTER(
+ static const char* fragmentGrayscaleFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
lowp float amount = 1.0 - u_amount;
@@ -409,9 +298,9 @@ StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterO
color.a);
}
);
- break;
- case FilterOperation::SEPIA:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentSepiaFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
lowp float amount = 1.0 - u_amount;
@@ -421,9 +310,9 @@ StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterO
color.a);
}
);
- break;
- case FilterOperation::SATURATE:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentSaturateFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
return vec4((0.213 + 0.787 * u_amount) * color.r + (0.715 - 0.715 * u_amount) * color.g + (0.072 - 0.072 * u_amount) * color.b,
@@ -432,9 +321,9 @@ StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterO
color.a);
}
);
- break;
- case FilterOperation::HUE_ROTATE:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentHueRotateFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
highp float pi = 3.14159265358979323846;
@@ -446,58 +335,62 @@ StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterO
color.a);
}
);
- break;
- case FilterOperation::INVERT:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentInvertFilter =
+ STANDARD_FILTER(
lowp float invert(lowp float n) { return (1.0 - n) * u_amount + n * (1.0 - u_amount); }
lowp vec4 shade(lowp vec4 color)
{
return vec4(invert(color.r), invert(color.g), invert(color.b), color.a);
}
);
- break;
- case FilterOperation::BRIGHTNESS:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentBrightnessFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
return vec4(color.rgb * (1.0 + u_amount), color.a);
}
);
- break;
- case FilterOperation::CONTRAST:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentContrastFilter =
+ STANDARD_FILTER(
lowp float contrast(lowp float n) { return (n - 0.5) * u_amount + 0.5; }
lowp vec4 shade(lowp vec4 color)
{
return vec4(contrast(color.r), contrast(color.g), contrast(color.b), color.a);
}
);
- break;
- case FilterOperation::OPACITY:
- fragmentShaderSource = STANDARD_FILTER(
+
+ static const char* fragmentOpacityFilter =
+ STANDARD_FILTER(
lowp vec4 shade(lowp vec4 color)
{
return vec4(color.r, color.g, color.b, color.a * u_amount);
}
);
- break;
- case FilterOperation::BLUR:
- fragmentShaderSource = STRINGIFY(
+
+#define BLUR_CONSTANTS "#define GAUSSIAN_KERNEL_HALF_WIDTH 11\n#define GAUSSIAN_KERNEL_STEP 0.2\n"
+
+ static const char* fragmentBlurFilter =
+ BLUR_CONSTANTS
+ STRINGIFY(
+ // Create a normal distribution of 21 values between -2 and 2.
precision mediump float;
varying highp vec2 v_texCoord;
uniform lowp vec2 u_blurRadius;
- uniform sampler2D u_texture;
+ uniform sampler2D s_sampler;
uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
lowp vec4 sampleColor(float radius)
{
vec2 coord = v_texCoord + radius * u_blurRadius;
- return texture2D(u_texture, coord) * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
+ return texture2D(s_sampler, coord) * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
}
vec4 blur()
{
- vec4 total = sampleColor(0) * u_gaussianKernel[0];
+ vec4 total = sampleColor(0.) * u_gaussianKernel[0];
for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
total += sampleColor(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
total += sampleColor(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
@@ -511,282 +404,130 @@ StandardFilterProgram::StandardFilterProgram(GraphicsContext3D* context, FilterO
gl_FragColor = blur();
}
);
- break;
- case FilterOperation::DROP_SHADOW:
- switch (pass) {
- case 0: {
- // First pass: horizontal alpha blur.
- fragmentShaderSource = STRINGIFY(
- precision mediump float;
- varying highp vec2 v_texCoord;
- uniform lowp float u_shadowBlurRadius;
- uniform lowp vec2 u_shadowOffset;
- uniform sampler2D u_texture;
- uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
-
- lowp float sampleAlpha(float radius)
- {
- vec2 coord = v_texCoord - u_shadowOffset + vec2(radius * u_shadowBlurRadius, 0.);
- return texture2D(u_texture, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
- }
- lowp float shadowBlurHorizontal()
- {
- float total = sampleAlpha(0) * u_gaussianKernel[0];
- for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
- total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
- total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
- }
-
- return total;
- }
+ static const char* fragmentShadowFilter1 =
+ BLUR_CONSTANTS
+ STRINGIFY(
+ precision mediump float;
+ varying highp vec2 v_texCoord;
+ uniform lowp float u_blurRadius;
+ uniform lowp vec2 u_shadowOffset;
+ uniform sampler2D s_sampler;
+ uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
- void main(void)
- {
- gl_FragColor = vec4(1., 1., 1., 1.) * shadowBlurHorizontal();
- }
- );
- break;
+ lowp float sampleAlpha(float radius)
+ {
+ vec2 coord = v_texCoord - u_shadowOffset + vec2(radius * u_blurRadius, 0.);
+ return texture2D(s_sampler, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
}
- case 1: {
- // Second pass: vertical alpha blur and composite with origin.
- fragmentShaderSource = STRINGIFY(
- precision mediump float;
- varying highp vec2 v_texCoord;
- uniform lowp float u_shadowBlurRadius;
- uniform lowp vec4 u_shadowColor;
- uniform sampler2D u_texture;
- uniform sampler2D u_contentTexture;
- uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
-
- lowp float sampleAlpha(float r)
- {
- vec2 coord = v_texCoord + vec2(0., r * u_shadowBlurRadius);
- return texture2D(u_texture, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
- }
-
- lowp float shadowBlurVertical()
- {
- float total = sampleAlpha(0) * u_gaussianKernel[0];
- for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
- total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
- total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
- }
- return total;
- }
-
- lowp vec4 sourceOver(lowp vec4 source, lowp vec4 destination)
- {
- // Composite the shadow with the original texture.
- return source + destination * (1. - source.a);
+ lowp float shadowBlurHorizontal()
+ {
+ float total = sampleAlpha(0.) * u_gaussianKernel[0];
+ for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
+ total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
+ total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
}
- void main(void)
- {
- gl_FragColor = sourceOver(texture2D(u_contentTexture, v_texCoord), shadowBlurVertical() * u_shadowColor);
- }
- );
- break;
+ return total;
}
- break;
- }
- default:
- break;
- }
- if (!fragmentShaderSource)
- return;
- Platform3DObject vertexShader = m_context->createShader(GraphicsContext3D::VERTEX_SHADER);
- Platform3DObject fragmentShader = m_context->createShader(GraphicsContext3D::FRAGMENT_SHADER);
- m_context->shaderSource(vertexShader, vertexShaderSource);
- m_context->shaderSource(fragmentShader, fragmentShaderSource);
- Platform3DObject programID = m_context->createProgram();
- m_context->compileShader(vertexShader);
- m_context->compileShader(fragmentShader);
-#if !LOG_DISABLED
- String log;
- m_context->getShaderInfoLog(fragmentShader);
- WTFLog(&LogCompositing, "%s\n", log.ascii().data());
-#endif
- m_context->attachShader(programID, vertexShader);
- m_context->attachShader(programID, fragmentShader);
- m_context->linkProgram(programID);
+ void main(void)
+ {
+ gl_FragColor = vec4(1., 1., 1., 1.) * shadowBlurHorizontal();
+ }
+ );
- m_vertexAttrib = m_context->getAttribLocation(programID, "a_vertex");
- m_texCoordAttrib = m_context->getAttribLocation(programID, "a_texCoord");
- m_textureUniformLocation = m_context->getUniformLocation(programID, "u_texture");
- switch (type) {
- case FilterOperation::GRAYSCALE:
- case FilterOperation::SEPIA:
- case FilterOperation::SATURATE:
- case FilterOperation::HUE_ROTATE:
- case FilterOperation::INVERT:
- case FilterOperation::BRIGHTNESS:
- case FilterOperation::CONTRAST:
- case FilterOperation::OPACITY:
- m_uniformLocations.amount = m_context->getUniformLocation(programID, "u_amount");
- break;
- case FilterOperation::BLUR:
- m_uniformLocations.blur.radius = m_context->getUniformLocation(programID, "u_blurRadius");
- m_uniformLocations.blur.gaussianKernel = m_context->getUniformLocation(programID, "u_gaussianKernel");
- break;
- case FilterOperation::DROP_SHADOW:
- m_uniformLocations.shadow.blurRadius = m_context->getUniformLocation(programID, "u_shadowBlurRadius");
- m_uniformLocations.shadow.gaussianKernel = m_context->getUniformLocation(programID, "u_gaussianKernel");
- if (!pass)
- m_uniformLocations.shadow.offset = m_context->getUniformLocation(programID, "u_shadowOffset");
- else {
- // We only need the color and the content texture in the second pass, the first pass is only a horizontal alpha blur.
- m_uniformLocations.shadow.color = m_context->getUniformLocation(programID, "u_shadowColor");
- m_uniformLocations.shadow.contentTexture = m_context->getUniformLocation(programID, "u_contentTexture");
- }
- break;
- default:
- break;
- }
- m_id = programID;
- m_vertexShader = vertexShader;
- m_fragmentShader = fragmentShader;
-}
+ // Second pass: vertical alpha blur and composite with origin.
+ static const char* fragmentShadowFilter2 =
+ BLUR_CONSTANTS
+ STRINGIFY(
+ precision mediump float;
+ varying highp vec2 v_texCoord;
+ uniform lowp float u_blurRadius;
+ uniform lowp vec4 u_shadowColor;
+ uniform sampler2D s_sampler;
+ uniform sampler2D s_contentTexture;
+ uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
-PassRefPtr<StandardFilterProgram> StandardFilterProgram::create(GraphicsContext3D* context, FilterOperation::OperationType type, unsigned pass)
-{
- RefPtr<StandardFilterProgram> program = adoptRef(new StandardFilterProgram(context, type, pass));
- if (!program->m_id)
- return 0;
+ lowp float sampleAlpha(float r)
+ {
+ vec2 coord = v_texCoord + vec2(0., r * u_blurRadius);
+ return texture2D(s_sampler, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
+ }
- return program;
-}
+ lowp float shadowBlurVertical()
+ {
+ float total = sampleAlpha(0.) * u_gaussianKernel[0];
+ for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
+ total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
+ total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
+ }
-static inline float gauss(float x)
-{
- return exp(-(x * x) / 2.);
-}
+ return total;
+ }
-static float* gaussianKernel()
-{
- static bool prepared = false;
- static float kernel[GAUSSIAN_KERNEL_HALF_WIDTH] = {0, };
+ lowp vec4 sourceOver(lowp vec4 source, lowp vec4 destination)
+ {
+ // Composite the shadow with the original texture.
+ return source + destination * (1. - source.a);
+ }
- if (prepared)
- return kernel;
+ void main(void)
+ {
+ gl_FragColor = sourceOver(texture2D(s_contentTexture, v_texCoord), shadowBlurVertical() * u_shadowColor);
+ }
+ );
- kernel[0] = gauss(0);
- float sum = kernel[0];
- for (unsigned i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; ++i) {
- kernel[i] = gauss(i * GAUSSIAN_KERNEL_STEP);
- sum += 2 * kernel[i];
+ if (specs.isEmpty()) {
+ specs.resize(TextureMapperShaderManager::LastFilter);
+ specs[TextureMapperShaderManager::Default] = ShaderSpec(vertexSimple, fragmentSimple);
+ specs[TextureMapperShaderManager::SolidColor] = ShaderSpec(vertexSolidColor, fragmentSolidColor);
+ specs[TextureMapperShaderManager::Rect] = ShaderSpec(vertexSimple, fragmentRectSimple);
+ specs[TextureMapperShaderManager::Masked] = ShaderSpec(vertexOpacityAndMask, fragmentOpacityAndMask);
+ specs[TextureMapperShaderManager::MaskedRect] = ShaderSpec(vertexOpacityAndMask, fragmentRectOpacityAndMask);
+ specs[TextureMapperShaderManager::Antialiased] = ShaderSpec(vertexSimple, fragmentAntialiasingNoMask);
+ specs[TextureMapperShaderManager::GrayscaleFilter] = ShaderSpec(vertexFilter, fragmentGrayscaleFilter);
+ specs[TextureMapperShaderManager::SepiaFilter] = ShaderSpec(vertexFilter, fragmentSepiaFilter);
+ specs[TextureMapperShaderManager::SaturateFilter] = ShaderSpec(vertexFilter, fragmentSaturateFilter);
+ specs[TextureMapperShaderManager::HueRotateFilter] = ShaderSpec(vertexFilter, fragmentHueRotateFilter);
+ specs[TextureMapperShaderManager::BrightnessFilter] = ShaderSpec(vertexFilter, fragmentBrightnessFilter);
+ specs[TextureMapperShaderManager::ContrastFilter] = ShaderSpec(vertexFilter, fragmentContrastFilter);
+ specs[TextureMapperShaderManager::InvertFilter] = ShaderSpec(vertexFilter, fragmentInvertFilter);
+ specs[TextureMapperShaderManager::OpacityFilter] = ShaderSpec(vertexFilter, fragmentOpacityFilter);
+ specs[TextureMapperShaderManager::BlurFilter] = ShaderSpec(vertexFilter, fragmentBlurFilter);
+ specs[TextureMapperShaderManager::ShadowFilterPass1] = ShaderSpec(vertexFilter, fragmentShadowFilter1);
+ specs[TextureMapperShaderManager::ShadowFilterPass2] = ShaderSpec(vertexFilter, fragmentShadowFilter2);
}
- // Normalize the kernel
- float scale = 1 / sum;
- for (unsigned i = 0; i < GAUSSIAN_KERNEL_HALF_WIDTH; ++i)
- kernel[i] *= scale;
-
- prepared = true;
- return kernel;
+ ASSERT(specs.size() > key);
+ ShaderSpec& spec = specs[key];
+ vertexSource = spec.vertexShader;
+ fragmentSource = spec.fragmentShader;
}
-void StandardFilterProgram::prepare(const FilterOperation& operation, unsigned pass, const IntSize& size, GC3Duint contentTexture)
+TextureMapperShaderManager::TextureMapperShaderManager(GraphicsContext3D* context)
+ : m_context(context)
{
- m_context->useProgram(m_id);
- switch (operation.getOperationType()) {
- case FilterOperation::GRAYSCALE:
- case FilterOperation::SEPIA:
- case FilterOperation::SATURATE:
- case FilterOperation::HUE_ROTATE:
- m_context->uniform1f(m_uniformLocations.amount, static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
- break;
- case FilterOperation::INVERT:
- case FilterOperation::BRIGHTNESS:
- case FilterOperation::CONTRAST:
- case FilterOperation::OPACITY:
- m_context->uniform1f(m_uniformLocations.amount, static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
- break;
- case FilterOperation::BLUR: {
- const BlurFilterOperation& blur = static_cast<const BlurFilterOperation&>(operation);
- FloatSize radius;
-
- // Blur is done in two passes, first horizontally and then vertically. The same shader is used for both.
- if (pass)
- radius.setHeight(floatValueForLength(blur.stdDeviation(), size.height()) / size.height());
- else
- radius.setWidth(floatValueForLength(blur.stdDeviation(), size.width()) / size.width());
-
- m_context->uniform2f(m_uniformLocations.blur.radius, radius.width(), radius.height());
- m_context->uniform1fv(m_uniformLocations.blur.gaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH, gaussianKernel());
- break;
- }
- case FilterOperation::DROP_SHADOW: {
- const DropShadowFilterOperation& shadow = static_cast<const DropShadowFilterOperation&>(operation);
- switch (pass) {
- case 0:
- // First pass: vertical alpha blur.
- m_context->uniform2f(m_uniformLocations.shadow.offset, float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
- m_context->uniform1f(m_uniformLocations.shadow.blurRadius, shadow.stdDeviation() / float(size.width()));
- m_context->uniform1fv(m_uniformLocations.shadow.gaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH, gaussianKernel());
- break;
- case 1:
- // Second pass: we need the shadow color and the content texture for compositing.
- m_context->uniform1f(m_uniformLocations.shadow.blurRadius, shadow.stdDeviation() / float(size.height()));
- m_context->uniform1fv(m_uniformLocations.shadow.gaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH, gaussianKernel());
- m_context->activeTexture(GraphicsContext3D::TEXTURE1);
- m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, contentTexture);
- m_context->uniform1i(m_uniformLocations.shadow.contentTexture, 1);
- float r, g, b, a;
- shadow.color().getRGBA(r, g, b, a);
- m_context->uniform4f(m_uniformLocations.shadow.color, r, g, b, a);
- break;
- }
- break;
- }
- default:
- break;
- }
}
-PassRefPtr<StandardFilterProgram> TextureMapperShaderManager::getShaderForFilter(const FilterOperation& filter, unsigned pass)
+TextureMapperShaderManager::~TextureMapperShaderManager()
{
- RefPtr<StandardFilterProgram> program;
- FilterOperation::OperationType type = filter.getOperationType();
- int key = int(type) | (pass << 16);
- FilterMap::iterator iterator = m_filterMap.find(key);
- if (iterator == m_filterMap.end()) {
- program = StandardFilterProgram::create(m_context, type, pass);
- if (!program)
- return 0;
-
- m_filterMap.add(key, program);
- } else
- program = iterator->second;
-
- return program;
}
-unsigned TextureMapperShaderManager::getPassesRequiredForFilter(const FilterOperation& operation) const
+PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProgram(ShaderKey key)
{
- switch (operation.getOperationType()) {
- case FilterOperation::GRAYSCALE:
- case FilterOperation::SEPIA:
- case FilterOperation::SATURATE:
- case FilterOperation::HUE_ROTATE:
- case FilterOperation::INVERT:
- case FilterOperation::BRIGHTNESS:
- case FilterOperation::CONTRAST:
- case FilterOperation::OPACITY:
- return 1;
- case FilterOperation::BLUR:
- case FilterOperation::DROP_SHADOW:
- // We use two-passes (vertical+horizontal) for blur and drop-shadow.
- return 2;
- default:
- return 0;
- }
-
+ TextureMapperShaderProgramMap::iterator it = m_programs.find(key);
+ if (it != m_programs.end())
+ return it->value;
+
+ String vertexShader;
+ String fragmentShader;
+ getShaderSpec(key, vertexShader, fragmentShader);
+ RefPtr<TextureMapperShaderProgram> program = TextureMapperShaderProgram::create(m_context, vertexShader, fragmentShader);
+ m_programs.add(key, program);
+ return program;
}
-
-#endif
};
#endif
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
index 1ffb7100b..b1f8d6107 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h
@@ -21,233 +21,102 @@
#ifndef TextureMapperShaderManager_h
#define TextureMapperShaderManager_h
-#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
-
-#include "FloatQuad.h"
+#if USE(TEXTURE_MAPPER)
#include "GraphicsContext3D.h"
-#include "IntSize.h"
#include "TextureMapperGL.h"
-#include "TransformationMatrix.h"
#include <wtf/HashMap.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
-#include <wtf/text/CString.h>
-
-#if ENABLE(CSS_FILTERS)
-#include "FilterOperations.h"
-#endif
+#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
-
-class BitmapTexture;
-class TextureMapperShaderManager;
+#define TEXMAP_DECLARE_VARIABLE(Accessor, Name, Type) GC3Duint Accessor##Location() { static const AtomicString name(Name); return getLocation(name, Type); }
+#define TEXMAP_DECLARE_UNIFORM(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "u_"#Accessor, UniformVariable)
+#define TEXMAP_DECLARE_ATTRIBUTE(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "a_"#Accessor, AttribVariable)
+#define TEXMAP_DECLARE_SAMPLER(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "s_"#Accessor, UniformVariable)
class TextureMapperShaderProgram : public RefCounted<TextureMapperShaderProgram> {
public:
- Platform3DObject id() { return m_id; }
- GC3Duint vertexAttrib() { return m_vertexAttrib; }
+ Platform3DObject programID() const { return m_id; }
+ GraphicsContext3D* context() { return m_context.get(); }
+ static PassRefPtr<TextureMapperShaderProgram> create(PassRefPtr<GraphicsContext3D> context, const String& vertex, const String& fragment)
+ {
+ return adoptRef(new TextureMapperShaderProgram(context, vertex, fragment));
+ }
- TextureMapperShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
virtual ~TextureMapperShaderProgram();
- virtual void prepare(float opacity, const BitmapTexture*) { }
- GC3Dint matrixLocation() const { return m_matrixLocation; }
- GC3Dint flipLocation() const { return m_flipLocation; }
- GC3Dint textureSizeLocation() const { return m_textureSizeLocation; }
- GC3Dint sourceTextureLocation() const { return m_sourceTextureLocation; }
- GC3Dint maskTextureLocation() const { return m_maskTextureLocation; }
- GC3Dint opacityLocation() const { return m_opacityLocation; }
-
- static bool isValidUniformLocation(GC3Dint location) { return location >= 0; }
-
-protected:
- void getUniformLocation(GC3Dint& var, const char* name);
- void initializeProgram();
- virtual void initialize() { }
- const char* vertexShaderSource() const { return m_vertexShaderSource.data(); }
- const char* fragmentShaderSource() const { return m_fragmentShaderSource.data(); }
+ TEXMAP_DECLARE_ATTRIBUTE(vertex)
+ TEXMAP_DECLARE_ATTRIBUTE(texCoord)
- GraphicsContext3D* m_context;
- Platform3DObject m_id;
- GC3Duint m_vertexAttrib;
- Platform3DObject m_vertexShader;
- Platform3DObject m_fragmentShader;
- GC3Dint m_matrixLocation;
- GC3Dint m_flipLocation;
- GC3Dint m_textureSizeLocation;
- GC3Dint m_sourceTextureLocation;
- GC3Dint m_opacityLocation;
- GC3Dint m_maskTextureLocation;
-
-private:
- CString m_vertexShaderSource;
- CString m_fragmentShaderSource;
-};
+ TEXMAP_DECLARE_UNIFORM(matrix)
+ TEXMAP_DECLARE_UNIFORM(flip)
+ TEXMAP_DECLARE_UNIFORM(textureSize)
+ TEXMAP_DECLARE_UNIFORM(opacity)
+ TEXMAP_DECLARE_UNIFORM(color)
+ TEXMAP_DECLARE_UNIFORM(expandedQuadEdgesInScreenSpace)
+ TEXMAP_DECLARE_SAMPLER(sampler)
+ TEXMAP_DECLARE_SAMPLER(mask)
#if ENABLE(CSS_FILTERS)
-class StandardFilterProgram : public RefCounted<StandardFilterProgram> {
-public:
- virtual ~StandardFilterProgram();
- virtual void prepare(const FilterOperation&, unsigned pass, const IntSize&, GC3Duint contentTexture);
- static PassRefPtr<StandardFilterProgram> create(GraphicsContext3D*, FilterOperation::OperationType, unsigned pass);
- GC3Duint vertexAttrib() const { return m_vertexAttrib; }
- GC3Duint texCoordAttrib() const { return m_texCoordAttrib; }
- GC3Duint textureUniform() const { return m_textureUniformLocation; }
-protected:
- GraphicsContext3D* m_context;
-private:
- StandardFilterProgram();
- StandardFilterProgram(GraphicsContext3D*, FilterOperation::OperationType, unsigned pass);
- Platform3DObject m_id;
- Platform3DObject m_vertexShader;
- Platform3DObject m_fragmentShader;
- GC3Duint m_vertexAttrib;
- GC3Duint m_texCoordAttrib;
- GC3Duint m_textureUniformLocation;
- union {
- GC3Duint amount;
-
- struct {
- GC3Duint radius;
- GC3Duint gaussianKernel;
- } blur;
-
- struct {
- GC3Duint blurRadius;
- GC3Duint color;
- GC3Duint offset;
- GC3Duint contentTexture;
- GC3Duint gaussianKernel;
- } shadow;
- } m_uniformLocations;
-};
+ TEXMAP_DECLARE_UNIFORM(amount)
+ TEXMAP_DECLARE_UNIFORM(gaussianKernel)
+ TEXMAP_DECLARE_UNIFORM(blurRadius)
+ TEXMAP_DECLARE_UNIFORM(shadowColor)
+ TEXMAP_DECLARE_UNIFORM(shadowOffset)
+ TEXMAP_DECLARE_SAMPLER(contentTexture)
#endif
-class TextureMapperShaderProgramSimple : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramSimple> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramSimple(context));
- }
-
-protected:
- TextureMapperShaderProgramSimple(GraphicsContext3D*);
-private:
- TextureMapperShaderProgramSimple();
-};
-
-class TextureMapperShaderProgramRectSimple : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramRectSimple> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramRectSimple(context));
- }
-
-protected:
- TextureMapperShaderProgramRectSimple(GraphicsContext3D*);
private:
- TextureMapperShaderProgramRectSimple();
-};
-
-class TextureMapperShaderProgramOpacityAndMask : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramOpacityAndMask> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramOpacityAndMask(context));
- }
-
-protected:
- TextureMapperShaderProgramOpacityAndMask(GraphicsContext3D*);
-private:
- TextureMapperShaderProgramOpacityAndMask();
-};
-
-class TextureMapperShaderProgramRectOpacityAndMask : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramRectOpacityAndMask> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramRectOpacityAndMask(context));
- }
-
-protected:
- TextureMapperShaderProgramRectOpacityAndMask(GraphicsContext3D*);
-private:
- TextureMapperShaderProgramRectOpacityAndMask();
-};
-
-class TextureMapperShaderProgramSolidColor : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramSolidColor> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramSolidColor(context));
- }
-
- GC3Dint colorLocation() const { return m_colorLocation; }
-
-protected:
- TextureMapperShaderProgramSolidColor(GraphicsContext3D*);
-private:
- TextureMapperShaderProgramSolidColor();
- GC3Dint m_colorLocation;
-};
-
-class TextureMapperShaderProgramAntialiasingNoMask : public TextureMapperShaderProgram {
-public:
- static PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> create(GraphicsContext3D* context)
- {
- return adoptRef(new TextureMapperShaderProgramAntialiasingNoMask(context));
- }
-
- GC3Dint expandedQuadVerticesInTextureCoordinatesLocation() { return m_expandedQuadVerticesInTextureCordinatesLocation; }
- GC3Dint expandedQuadEdgesInScreenSpaceLocation() { return m_expandedQuadEdgesInScreenSpaceLocation; }
+ TextureMapperShaderProgram(PassRefPtr<GraphicsContext3D>, const String& vertexShaderSource, const String& fragmentShaderSource);
+ Platform3DObject m_vertexShader;
+ Platform3DObject m_fragmentShader;
-protected:
- TextureMapperShaderProgramAntialiasingNoMask(GraphicsContext3D*);
-private:
- TextureMapperShaderProgramAntialiasingNoMask();
+ enum VariableType { UniformVariable, AttribVariable };
+ GC3Duint getLocation(const AtomicString&, VariableType);
- GC3Dint m_expandedQuadVerticesInTextureCordinatesLocation;
- GC3Dint m_expandedQuadEdgesInScreenSpaceLocation;
+ RefPtr<GraphicsContext3D> m_context;
+ Platform3DObject m_id;
+ HashMap<AtomicString, GC3Duint> m_variables;
};
class TextureMapperShaderManager {
public:
- enum ShaderType {
- Invalid = 0, // HashMaps do not like 0 as a key.
- Simple,
- AntialiasingNoMask,
- RectSimple,
- OpacityAndMask,
- RectOpacityAndMask,
- SolidColor
+ enum ShaderKey {
+ Invalid = 0,
+ Default,
+ Rect,
+ Masked,
+ MaskedRect,
+ SolidColor,
+ Antialiased,
+ GrayscaleFilter,
+ SepiaFilter,
+ SaturateFilter,
+ HueRotateFilter,
+ BrightnessFilter,
+ ContrastFilter,
+ OpacityFilter,
+ InvertFilter,
+ BlurFilter,
+ ShadowFilterPass1,
+ ShadowFilterPass2,
+ LastFilter
};
TextureMapperShaderManager() { }
TextureMapperShaderManager(GraphicsContext3D*);
virtual ~TextureMapperShaderManager();
-#if ENABLE(CSS_FILTERS)
- unsigned getPassesRequiredForFilter(const FilterOperation&) const;
- PassRefPtr<StandardFilterProgram> getShaderForFilter(const FilterOperation&, unsigned pass);
-#endif
-
- PassRefPtr<TextureMapperShaderProgram> getShaderProgram(ShaderType);
- PassRefPtr<TextureMapperShaderProgramSolidColor> solidColorProgram();
- PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> antialiasingNoMaskProgram();
+ PassRefPtr<TextureMapperShaderProgram> getShaderProgram(ShaderKey);
private:
- typedef HashMap<ShaderType, RefPtr<TextureMapperShaderProgram>, DefaultHash<int>::Hash, HashTraits<int> > TextureMapperShaderProgramMap;
- TextureMapperShaderProgramMap m_textureMapperShaderProgramMap;
- GraphicsContext3D* m_context;
-
-#if ENABLE(CSS_FILTERS)
- typedef HashMap<int, RefPtr<StandardFilterProgram> > FilterMap;
- FilterMap m_filterMap;
-#endif
+ typedef HashMap<ShaderKey, RefPtr<TextureMapperShaderProgram>, DefaultHash<int>::Hash, HashTraits<int> > TextureMapperShaderProgramMap;
+ TextureMapperShaderProgramMap m_programs;
+ RefPtr<GraphicsContext3D> m_context;
};
}
-
#endif
#endif // TextureMapperShaderManager_h
diff --git a/Source/WebCore/platform/graphics/win/FontCGWin.cpp b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
index b367bb79d..170c9f07c 100644
--- a/Source/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -197,19 +197,19 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
// If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
float shadowTextY = point.y() + translation.height() + shadowOffset.height() * (graphicsContext->shadowsIgnoreTransforms() ? -1 : 1);
CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
- CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowOffset.height());
- CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
}
graphicsContext->setFillColor(fillColor, ColorSpaceDeviceRGB);
}
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
- CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->syntheticBoldOffset(), point.y() + translation.height());
- CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
+ CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
}
if (hasSimpleShadow)
diff --git a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
index f54897a9b..2540fae97 100644
--- a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -186,10 +186,10 @@ static HFONT createMLangFont(IMLangFontLink2* langFontLink, HDC hdc, DWORD codeP
return hfont;
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
UChar character = characters[0];
- SimpleFontData* fontData = 0;
+ RefPtr<SimpleFontData> fontData;
HWndDC hdc(0);
HFONT primaryFont = font.primaryFont()->fontDataForCharacter(character)->platformData().hfont();
HGDIOBJ oldFont = SelectObject(hdc, primaryFont);
@@ -293,24 +293,24 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
DeleteObject(hfont);
}
- return fontData;
+ return fontData.release();
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
}
-SimpleFontData* FontCache::fontDataFromDescriptionAndLogFont(const FontDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, AtomicString& outFontFamilyName)
+PassRefPtr<SimpleFontData> FontCache::fontDataFromDescriptionAndLogFont(const FontDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, AtomicString& outFontFamilyName)
{
AtomicString familyName = String(font.lfFaceName, wcsnlen(font.lfFaceName, LF_FACESIZE));
- SimpleFontData* fontData = getCachedFontData(fontDescription, familyName, false, shouldRetain);
+ RefPtr<SimpleFontData> fontData = getCachedFontData(fontDescription, familyName, false, shouldRetain);
if (fontData)
outFontFamilyName = familyName;
- return fontData;
+ return fontData.release();
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
DEFINE_STATIC_LOCAL(AtomicString, fallbackFontName, ());
if (!fallbackFontName.isEmpty())
@@ -329,11 +329,11 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
AtomicString("Lucida Sans Unicode"),
AtomicString("Arial")
};
- SimpleFontData* simpleFont;
+ RefPtr<SimpleFontData> simpleFont;
for (size_t i = 0; i < WTF_ARRAY_LENGTH(fallbackFonts); ++i) {
if (simpleFont = getCachedFontData(fontDescription, fallbackFonts[i], false, shouldRetain)) {
fallbackFontName = fallbackFonts[i];
- return simpleFont;
+ return simpleFont.release();
}
}
@@ -342,7 +342,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
LOGFONT defaultGUILogFont;
GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont);
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, defaultGUILogFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
}
// Fall back to Non-client metrics fonts.
@@ -350,15 +350,15 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
nonClientMetrics.cbSize = sizeof(nonClientMetrics);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) {
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, nonClientMetrics.lfMessageFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, nonClientMetrics.lfMenuFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, nonClientMetrics.lfStatusFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, nonClientMetrics.lfCaptionFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
if (simpleFont = fontDataFromDescriptionAndLogFont(fontDescription, shouldRetain, nonClientMetrics.lfSmCaptionFont, fallbackFontName))
- return simpleFont;
+ return simpleFont.release();
}
ASSERT_NOT_REACHED();
diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
index c33cce58d..35c3d7778 100644
--- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
+++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -101,7 +101,7 @@ private:
virtual GraphicsLayer::CompositingCoordinatesOrientation platformCALayerContentsOrientation() const { return GraphicsLayer::CompositingCoordinatesBottomUp; }
virtual void platformCALayerPaintContents(GraphicsContext&, const IntRect& inClip) { }
virtual bool platformCALayerShowDebugBorders() const { return false; }
- virtual bool platformCALayerShowRepaintCounter() const { return false; }
+ virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const { return false; }
virtual int platformCALayerIncrementRepaintCount() { return 0; }
virtual bool platformCALayerContentsOpaque() const { return false; }
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 53af06d64..72323518f 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -132,40 +132,40 @@ void SimpleFontData::platformDestroy()
delete m_scriptFontProperties;
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
float scaledSize = scaleFactor * m_platformData.size();
if (isCustomFont()) {
FontPlatformData scaledFont(m_platformData);
scaledFont.setSize(scaledSize);
- return adoptPtr(new SimpleFontData(scaledFont, true, false));
+ return SimpleFontData::create(scaledFont, true, false);
}
LOGFONT winfont;
GetObject(m_platformData.hfont(), sizeof(LOGFONT), &winfont);
winfont.lfHeight = -lroundf(scaledSize * (m_platformData.useGDI() ? 1 : 32));
HFONT hfont = CreateFontIndirect(&winfont);
- return adoptPtr(new SimpleFontData(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false));
+ return SimpleFontData::create(FontPlatformData(hfont, scaledSize, m_platformData.syntheticBold(), m_platformData.syntheticOblique(), m_platformData.useGDI()), isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, cSmallCapsFontSizeMultiplier);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/Source/WebCore/platform/graphics/wince/FontCacheWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontCacheWinCE.cpp
index 86c61455a..7641edd2d 100644
--- a/Source/WebCore/platform/graphics/wince/FontCacheWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontCacheWinCE.cpp
@@ -225,7 +225,7 @@ void FontCache::comUninitialize()
}
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
String familyName;
WCHAR name[LF_FACESIZE];
@@ -235,10 +235,11 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
unsigned unicodeRange = findCharUnicodeRange(character);
#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2)
- if (IMLangFontLink2* langFontLink = getFontLinkInterface()) {
+ if (IMLangFontLink2* langFontLink = getFontLinkInterface())
#else
- if (IMLangFontLink* langFontLink = getFontLinkInterface()) {
+ if (IMLangFontLink* langFontLink = getFontLinkInterface())
#endif
+ {
HGDIOBJ oldFont = GetCurrentObject(g_screenDC, OBJ_FONT);
HFONT hfont = 0;
DWORD codePages = 0;
@@ -267,10 +268,11 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
// We asked about a code page that is not one of the code pages
// returned by MLang, so the font might not contain the character.
#if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2)
- if (!currentFontContainsCharacter(langFontLink, g_screenDC, character)) {
+ if (!currentFontContainsCharacter(langFontLink, g_screenDC, character))
#else
- if (!currentFontContainsCharacter(langFontLink, g_screenDC, hfont, character, name)) {
+ if (!currentFontContainsCharacter(langFontLink, g_screenDC, hfont, character, name))
#endif
+ {
SelectObject(g_screenDC, oldFont);
langFontLink->ReleaseFont(hfont);
hfont = 0;
@@ -308,20 +310,20 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
FontPlatformData* result = getCachedFontPlatformData(fontDescription, familyName);
if (result && result->hash() != origFont.hash()) {
- if (SimpleFontData* fontData = getCachedFontData(result, DoNotRetain))
- return fontData;
+ if (RefPtr<SimpleFontData> fontData = getCachedFontData(result, DoNotRetain))
+ return fontData.release();
}
}
return 0;
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font&)
{
return 0;
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDesc, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDesc, ShouldRetain shouldRetain)
{
// FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
// the default that the user would get without changing any prefs.
diff --git a/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp b/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
index 1266c5c1b..5a295bb40 100644
--- a/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontPlatformData.cpp
@@ -287,9 +287,9 @@ static PassRefPtr<FixedSizeFontData> createFixedSizeFontData(const AtomicString&
FixedSizeFontDataKey key(family, weight, italic);
FixedSizeFontCache::AddResult result = g_fixedSizeFontCache.add(key, RefPtr<FixedSizeFontData>());
if (result.isNewEntry)
- result.iterator->second = FixedSizeFontData::create(family, weight, italic);
+ result.iterator->value = FixedSizeFontData::create(family, weight, italic);
- return result.iterator->second;
+ return result.iterator->value;
}
static LONG toGDIFontWeight(FontWeight fontWeight)
@@ -463,11 +463,6 @@ const LOGFONT& FontPlatformData::logFont() const
return m_private->m_rootFontData->m_font;
}
-int FontPlatformData::averageCharWidth() const
-{
- return (m_private->m_rootFontData->m_metrics.tmAveCharWidth * size() + 36) / 72;
-}
-
bool FontPlatformData::isDisabled() const
{
return !isValid() || m_private->m_disabled;
diff --git a/Source/WebCore/platform/graphics/wince/FontPlatformData.h b/Source/WebCore/platform/graphics/wince/FontPlatformData.h
index 9c3f73345..00c946832 100644
--- a/Source/WebCore/platform/graphics/wince/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/wince/FontPlatformData.h
@@ -67,7 +67,6 @@ namespace WebCore {
bool operator==(const FontPlatformData& other) const { return m_private == other.m_private; }
HFONT getScaledFontHandle(int height, int width) const;
const LOGFONT& logFont() const;
- int averageCharWidth() const;
bool isDisabled() const;
bool discardFontHandle();
DWORD codePages() const;
diff --git a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
index 7aae13fb2..b98c46671 100644
--- a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp
@@ -313,7 +313,8 @@ static float cursorToX(const Font* font, const TextRunComponents& components, in
return xs + pos * comp.m_width / comp.m_spaces;
}
WidthIterator it(font, comp.m_textRun);
- it.advance(pos);
+ GlyphBuffer glyphBuffer;
+ it.advance(pos, &glyphBuffer);
return xs + it.m_runWidthSoFar;
}
return width;
diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
index 4e5f7e86e..1c93496f0 100644
--- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
@@ -1598,7 +1598,7 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
double scaleY = m_data->m_transform.d();
int height = fontData->platformData().size() * scaleY;
- int width = fontData->platformData().averageCharWidth() * scaleX;
+ int width = fontData->avgCharWidth() * scaleX;
if (!height || !width)
return;
@@ -1626,10 +1626,10 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
const GlyphBufferAdvance* advance = glyphBuffer.advances(from);
if (scaleX == 1.)
for (int i = 1; i < numGlyphs; ++i)
- offset += *advance++;
+ offset += (*advance++).width();
else
for (int i = 1; i < numGlyphs; ++i)
- offset += *advance++ * scaleX;
+ offset += (*advance++).width() * scaleX;
offset += width;
@@ -1687,7 +1687,7 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
bool drawOneByOne = false;
if (scaleX == 1.) {
for (; srcChar < srcCharEnd; ++srcChar) {
- offset += *advance++;
+ offset += (*advance++).width();
int offsetInt = stableRound(offset);
if (isCharVisible(*srcChar)) {
if (!drawOneByOne && WTF::Unicode::direction(*srcChar) == WTF::Unicode::RightToLeft)
@@ -1699,7 +1699,7 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
}
} else {
for (; srcChar < srcCharEnd; ++srcChar) {
- offset += *advance++ * scaleX;
+ offset += (*advance++).width() * scaleX;
int offsetInt = stableRound(offset);
if (isCharVisible(*srcChar)) {
if (!drawOneByOne && WTF::Unicode::direction(*srcChar) == WTF::Unicode::RightToLeft)
diff --git a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
index e3b842463..5925c7aa9 100644
--- a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
@@ -63,7 +63,7 @@ void SimpleFontData::platformDestroy()
{
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
FontDescription fontDesc(fontDescription);
fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize()));
@@ -71,28 +71,28 @@ PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize()));
FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
if (!result)
- return nullptr;
- return adoptPtr(new SimpleFontData(*result));
+ return 0;
+ return SimpleFontData::create(*result);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
DWORD getKnownFontCodePages(const wchar_t* family);
diff --git a/Source/WebCore/platform/graphics/wx/FontCacheWx.cpp b/Source/WebCore/platform/graphics/wx/FontCacheWx.cpp
index e0034ecd6..acd1dc3e1 100644
--- a/Source/WebCore/platform/graphics/wx/FontCacheWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/FontCacheWx.cpp
@@ -43,9 +43,9 @@ void FontCache::platformInit()
{
}
-const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
+PassRefPtr<SimpleFontData> FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
{
- SimpleFontData* fontData = 0;
+ RefPtr<SimpleFontData> fontData = 0;
fontData = getCachedFontData(font.fontDescription(), font.family().family(), false, DoNotRetain);
if (!fontData->containsCharacters(characters, length))
fontData = getSimilarFontPlatformData(font);
@@ -53,12 +53,12 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
fontData = getLastResortFallbackFont(font.fontDescription());
ASSERT(fontData);
- return fontData;
+ return fontData.release();
}
-SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
+PassRefPtr<SimpleFontData> FontCache::getSimilarFontPlatformData(const Font& font)
{
- SimpleFontData* simpleFontData = 0;
+ RefPtr<SimpleFontData> simpleFontData = 0;
#if OS(DARWIN)
// Attempt to find an appropriate font using a match based on
// the presence of keywords in the the requested names. For example, we'll
@@ -78,14 +78,14 @@ SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
if (!simpleFontData)
simpleFontData = getCachedFontData(font.fontDescription(), font.family().family());
- return simpleFontData;
+ return simpleFontData.release();
}
-SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
+PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain)
{
// FIXME: Would be even better to somehow get the user's default font here. For now we'll pick
// the default that the user would get without changing any prefs.
- SimpleFontData* fallback = 0;
+ RefPtr<SimpleFontData> fallback = 0;
#if OS(WINDOWS)
static AtomicString fallbackName("Arial Unicode MS");
#else
@@ -94,7 +94,7 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& font
fallback = getCachedFontData(fontDescription, fallbackName, false, shouldRetain);
ASSERT(fallback);
- return fallback;
+ return fallback.release();
}
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
diff --git a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index c2e4f2b84..e08a1540c 100644
--- a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -90,32 +90,32 @@ void SimpleFontData::platformDestroy()
#endif
}
-PassOwnPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
+PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
{
FontDescription desc = FontDescription(fontDescription);
desc.setSpecifiedSize(scaleFactor * fontDescription.computedSize());
FontPlatformData platformData(desc, desc.family().family());
- return adoptPtr(new SimpleFontData(platformData, isCustomFont(), false));
+ return SimpleFontData::create(platformData, isCustomFont(), false);
}
-SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->smallCaps)
m_derivedFontData->smallCaps = createScaledFontData(fontDescription, .7);
- return m_derivedFontData->smallCaps.get();
+ return m_derivedFontData->smallCaps;
}
-SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
+PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
{
if (!m_derivedFontData)
m_derivedFontData = DerivedFontData::create(isCustomFont());
if (!m_derivedFontData->emphasisMark)
m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, .5);
- return m_derivedFontData->emphasisMark.get();
+ return m_derivedFontData->emphasisMark;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
diff --git a/Source/WebCore/platform/gtk/AsyncFileSystemGtk.cpp b/Source/WebCore/platform/gtk/AsyncFileSystemGtk.cpp
index 8c0413efc..30fbda087 100644
--- a/Source/WebCore/platform/gtk/AsyncFileSystemGtk.cpp
+++ b/Source/WebCore/platform/gtk/AsyncFileSystemGtk.cpp
@@ -40,8 +40,7 @@ PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create()
return adoptPtr(new AsyncFileSystemGtk());
}
-// FIXME: Add FileSystemType parameter.
-void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, FileSystemType, bool, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
{
notImplemented();
callbacks->didFail(NOT_SUPPORTED_ERR);
diff --git a/Source/WebCore/platform/gtk/ClipboardGtk.cpp b/Source/WebCore/platform/gtk/ClipboardGtk.cpp
index 891126d5b..1eedb32d9 100644
--- a/Source/WebCore/platform/gtk/ClipboardGtk.cpp
+++ b/Source/WebCore/platform/gtk/ClipboardGtk.cpp
@@ -74,6 +74,8 @@ ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, PassRefPtr<DataObjectGt
ClipboardGtk::~ClipboardGtk()
{
+ if (m_dragImage)
+ m_dragImage->removeClient(this);
}
static ClipboardDataType dataObjectTypeFromHTMLClipboardType(const String& rawType)
@@ -184,15 +186,15 @@ bool ClipboardGtk::setData(const String& typeString, const String& data)
return success;
}
-HashSet<String> ClipboardGtk::types() const
+ListHashSet<String> ClipboardGtk::types() const
{
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
- return HashSet<String>();
+ return ListHashSet<String>();
if (m_clipboard)
PasteboardHelper::defaultPasteboardHelper()->getClipboardContents(m_clipboard);
- HashSet<String> types;
+ ListHashSet<String> types;
if (m_dataObject->hasText()) {
types.add("text/plain");
types.add("Text");
diff --git a/Source/WebCore/platform/gtk/ClipboardGtk.h b/Source/WebCore/platform/gtk/ClipboardGtk.h
index b071c6f7e..ee9d63ce4 100644
--- a/Source/WebCore/platform/gtk/ClipboardGtk.h
+++ b/Source/WebCore/platform/gtk/ClipboardGtk.h
@@ -57,7 +57,7 @@ namespace WebCore {
String getData(const String&) const;
bool setData(const String&, const String&);
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
void setDragImage(CachedImage*, const IntPoint&);
diff --git a/Source/WebCore/platform/gtk/DataObjectGtk.cpp b/Source/WebCore/platform/gtk/DataObjectGtk.cpp
index 1a84f8bd3..adfc66e01 100644
--- a/Source/WebCore/platform/gtk/DataObjectGtk.cpp
+++ b/Source/WebCore/platform/gtk/DataObjectGtk.cpp
@@ -171,7 +171,7 @@ DataObjectGtk* DataObjectGtk::forClipboard(GtkClipboard* clipboard)
}
HashMap<GtkClipboard*, RefPtr<DataObjectGtk> >::iterator it = objectMap.find(clipboard);
- return it->second.get();
+ return it->value.get();
}
}
diff --git a/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp b/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp
index 763d120d0..fc2f56e61 100644
--- a/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp
+++ b/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp
@@ -70,7 +70,7 @@ void GtkDragAndDropHelper::handleGetDragData(GdkDragContext* context, GtkSelecti
DraggingDataObjectsMap::iterator iterator = m_draggingDataObjects.find(context);
if (iterator == m_draggingDataObjects.end())
return;
- PasteboardHelper::defaultPasteboardHelper()->fillSelectionData(selectionData, info, iterator->second.get());
+ PasteboardHelper::defaultPasteboardHelper()->fillSelectionData(selectionData, info, iterator->value.get());
}
struct HandleDragLaterData {
@@ -116,7 +116,7 @@ void GtkDragAndDropHelper::handleDragLeave(GdkDragContext* gdkContext, DragExite
// the drag-drop signal. We want the actions for drag-leave to happen after
// those for drag-drop, so schedule them to happen asynchronously here.
HandleDragLaterData* data = new HandleDragLaterData;
- data->context = iterator->second;
+ data->context = iterator->value;
data->context->exitedCallback = exitedCallback;
data->glue = this;
g_timeout_add(0, reinterpret_cast<GSourceFunc>(handleDragLeaveLaterCallback), data);
@@ -140,7 +140,7 @@ PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragMotion(GdkDragContext* cont
m_droppingContexts.set(context, droppingContext);
queryNewDropContextData(droppingContext, m_widget, time);
} else {
- droppingContext = iterator->second;
+ droppingContext = iterator->value;
droppingContext->lastMotionPosition = position;
}
@@ -162,7 +162,7 @@ PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragDataReceived(GdkDragContext
if (iterator == m_droppingContexts.end())
return adoptPtr(static_cast<DragData*>(0));
- DroppingContext* droppingContext = iterator->second;
+ DroppingContext* droppingContext = iterator->value;
droppingContext->pendingDataRequests--;
PasteboardHelper::defaultPasteboardHelper()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get());
@@ -185,7 +185,7 @@ PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragDrop(GdkDragContext* contex
if (iterator == m_droppingContexts.end())
return adoptPtr(static_cast<DragData*>(0));
- DroppingContext* droppingContext = iterator->second;
+ DroppingContext* droppingContext = iterator->value;
droppingContext->dropHappened = true;
return adoptPtr(new DragData(droppingContext->dataObject.get(), position,
diff --git a/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp b/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp
index 0d7bdba43..e9118c77e 100644
--- a/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp
+++ b/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp
@@ -27,45 +27,102 @@
#include "config.h"
#include "RedirectedXCompositeWindow.h"
-#if USE(GLX)
-#include "GLContextGLX.h"
-#include <GL/glx.h>
+#if PLATFORM(X11)
#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
#include <cairo-xlib.h>
#include <gdk/gdkx.h>
#include <glib.h>
#include <gtk/gtk.h>
+#include <wtf/HashMap.h>
namespace WebCore {
+typedef HashMap<Window, RedirectedXCompositeWindow*> WindowHashMap;
+static WindowHashMap& getWindowHashMap()
+{
+ DEFINE_STATIC_LOCAL(WindowHashMap, windowHashMap, ());
+ return windowHashMap;
+}
+
+static int gDamageEventBase;
+static GdkFilterReturn filterXDamageEvent(GdkXEvent* gdkXEvent, GdkEvent* event, void*)
+{
+ XEvent* xEvent = static_cast<XEvent*>(gdkXEvent);
+ if (xEvent->type != gDamageEventBase + XDamageNotify)
+ return GDK_FILTER_CONTINUE;
+
+ XDamageNotifyEvent* damageEvent = reinterpret_cast<XDamageNotifyEvent*>(xEvent);
+ WindowHashMap& windowHashMap = getWindowHashMap();
+ WindowHashMap::iterator i = windowHashMap.find(damageEvent->drawable);
+ if (i == windowHashMap.end())
+ return GDK_FILTER_CONTINUE;
+
+ i->value->callDamageNotifyCallback();
+ XDamageSubtract(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), damageEvent->damage, None, None);
+ return GDK_FILTER_REMOVE;
+}
+
+static bool supportsXDamageAndXComposite()
+{
+ static bool initialized = false;
+ static bool hasExtensions = false;
+
+ if (initialized)
+ return hasExtensions;
+
+ initialized = true;
+
+ int errorBase;
+ Display* display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+ if (!XDamageQueryExtension(display, &gDamageEventBase, &errorBase))
+ return false;
+
+ int eventBase;
+ if (!XCompositeQueryExtension(display, &eventBase, &errorBase))
+ return false;
+
+ // We need to support XComposite version 0.2.
+ int major, minor;
+ XCompositeQueryVersion(display, &major, &minor);
+ if (major < 0 || (!major && minor < 2))
+ return false;
+
+ hasExtensions = true;
+ return true;
+}
+
PassOwnPtr<RedirectedXCompositeWindow> RedirectedXCompositeWindow::create(const IntSize& size)
{
- return adoptPtr(new RedirectedXCompositeWindow(size));
+ return supportsXDamageAndXComposite() ? adoptPtr(new RedirectedXCompositeWindow(size)) : nullptr;
}
RedirectedXCompositeWindow::RedirectedXCompositeWindow(const IntSize& size)
- : m_usableSize(size)
+ : m_size(size)
, m_window(0)
, m_parentWindow(0)
, m_pixmap(0)
, m_surface(0)
- , m_pendingResizeSourceId(0)
, m_needsNewPixmapAfterResize(false)
+ , m_damage(0)
+ , m_damageNotifyCallback(0)
+ , m_damageNotifyData(0)
{
- Display* display = GLContextGLX::sharedDisplay();
+ Display* display = GLContext::sharedX11Display();
+ Screen* screen = DefaultScreenOfDisplay(display);
// This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc
XSetWindowAttributes windowAttributes;
windowAttributes.override_redirect = True;
m_parentWindow = XCreateWindow(display,
- RootWindow(display, DefaultScreen(display)),
- -100, -100, 1, 1,
- 0,
- CopyFromParent,
- InputOutput,
- CopyFromParent,
- CWOverrideRedirect,
- &windowAttributes);
+ RootWindowOfScreen(screen),
+ WidthOfScreen(screen) + 1, 0, 1, 1,
+ 0,
+ CopyFromParent,
+ InputOutput,
+ CopyFromParent,
+ CWOverrideRedirect,
+ &windowAttributes);
XMapWindow(display, m_parentWindow);
windowAttributes.event_mask = StructureNotifyMask;
@@ -81,6 +138,10 @@ RedirectedXCompositeWindow::RedirectedXCompositeWindow(const IntSize& size)
&windowAttributes);
XMapWindow(display, m_window);
+ if (getWindowHashMap().isEmpty())
+ gdk_window_add_filter(0, reinterpret_cast<GdkFilterFunc>(filterXDamageEvent), 0);
+ getWindowHashMap().add(m_window, this);
+
while (1) {
XEvent event;
XWindowEvent(display, m_window, StructureNotifyMask, &event);
@@ -88,58 +149,34 @@ RedirectedXCompositeWindow::RedirectedXCompositeWindow(const IntSize& size)
break;
}
XSelectInput(display, m_window, NoEventMask);
-
XCompositeRedirectWindow(display, m_window, CompositeRedirectManual);
-
- resize(size);
+ m_damage = XDamageCreate(display, m_window, XDamageReportNonEmpty);
}
RedirectedXCompositeWindow::~RedirectedXCompositeWindow()
{
- Display* display = GLContextGLX::sharedDisplay();
- if (m_window)
- XDestroyWindow(display, m_window);
- if (m_parentWindow)
- XDestroyWindow(display, m_parentWindow);
- cleanupPixmapAndPixmapSurface();
-
- if (m_pendingResizeSourceId)
- g_source_remove(m_pendingResizeSourceId);
-}
+ ASSERT(m_damage);
+ ASSERT(m_window);
+ ASSERT(m_parentWindow);
-gboolean RedirectedXCompositeWindow::resizeLaterCallback(RedirectedXCompositeWindow* window)
-{
- window->resizeLater();
- return FALSE;
-}
+ getWindowHashMap().remove(m_window);
+ if (getWindowHashMap().isEmpty())
+ gdk_window_remove_filter(0, reinterpret_cast<GdkFilterFunc>(filterXDamageEvent), 0);
-void RedirectedXCompositeWindow::resizeLater()
-{
- m_usableSize = m_size;
- m_pendingResizeSourceId = 0;
+ Display* display = GLContext::sharedX11Display();
+ XDamageDestroy(display, m_damage);
+ XDestroyWindow(display, m_window);
+ XDestroyWindow(display, m_parentWindow);
+ cleanupPixmapAndPixmapSurface();
}
void RedirectedXCompositeWindow::resize(const IntSize& size)
{
- // When enlarging a redirected window, for the first render, the newly exposed areas seem
- // to contain uninitialized memory on Intel drivers. To avoid rendering artifacts while
- // resizing, we wait to render those new areas until after a short timeout. Thus, the
- // "usable size" of the window is smaller than the actual size of the window for the first
- // render.
- m_usableSize = size.shrunkTo(m_usableSize);
- if (m_usableSize.width() < size.width() || m_usableSize.height() < size.height()) { // The window is growing.
- // We're being very conservative here. Instead of risking drawing artifacts while doing continuous
- // opaque resizing, we err on the side of having more undrawn areas.
- if (m_pendingResizeSourceId)
- g_source_remove(m_pendingResizeSourceId);
- m_pendingResizeSourceId = g_timeout_add(0, reinterpret_cast<GSourceFunc>(resizeLaterCallback), this);
- }
-
- Display* display = GLContextGLX::sharedDisplay();
+ Display* display = GLContext::sharedX11Display();
XResizeWindow(display, m_window, size.width(), size.height());
XFlush(display);
- glXWaitX();
+ context()->waitNative();
// This swap is based on code in Chromium. It tries to work-around a bug in the Intel drivers
// where a swap is necessary to ensure the front and back buffers are properly resized.
@@ -216,6 +253,12 @@ cairo_surface_t* RedirectedXCompositeWindow::cairoSurfaceForWidget(GtkWidget* wi
return m_surface.get();
}
+void RedirectedXCompositeWindow::callDamageNotifyCallback()
+{
+ if (m_damageNotifyCallback)
+ m_damageNotifyCallback(m_damageNotifyData);
+}
+
} // namespace WebCore
-#endif // USE(GLX)
+#endif // PLATFORM(X11)
diff --git a/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h b/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h
index e5db0fa7e..7a98c3768 100644
--- a/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h
+++ b/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h
@@ -27,14 +27,16 @@
#ifndef RedirectedXCompositeWindow_h
#define RedirectedXCompositeWindow_h
-#if USE(GLX)
+#if PLATFORM(X11)
-#include "GLContextGLX.h"
+#include "GLContext.h"
#include "IntSize.h"
#include "RefPtrCairo.h"
typedef unsigned long Pixmap;
typedef unsigned long Window;
+typedef unsigned long Damage;
+typedef void (*DamageNotifyCallback)(void*);
namespace WebCore {
@@ -42,24 +44,25 @@ class RedirectedXCompositeWindow {
public:
static PassOwnPtr<RedirectedXCompositeWindow> create(const IntSize&);
virtual ~RedirectedXCompositeWindow();
-
- const IntSize& usableSize() { return m_usableSize; }
const IntSize& size() { return m_size; }
void resize(const IntSize& newSize);
GLContext* context();
cairo_surface_t* cairoSurfaceForWidget(GtkWidget*);
Window windowId() { return m_window; }
+ void callDamageNotifyCallback();
+
+ void setDamageNotifyCallback(DamageNotifyCallback callback, void* data)
+ {
+ m_damageNotifyCallback = callback;
+ m_damageNotifyData = data;
+ }
private:
RedirectedXCompositeWindow(const IntSize&);
-
- static gboolean resizeLaterCallback(RedirectedXCompositeWindow*);
- void resizeLater();
void cleanupPixmapAndPixmapSurface();
IntSize m_size;
- IntSize m_usableSize;
Window m_window;
Window m_parentWindow;
Pixmap m_pixmap;
@@ -67,10 +70,14 @@ private:
RefPtr<cairo_surface_t> m_surface;
unsigned int m_pendingResizeSourceId;
bool m_needsNewPixmapAfterResize;
+
+ Damage m_damage;
+ DamageNotifyCallback m_damageNotifyCallback;
+ void* m_damageNotifyData;
};
} // namespace WebCore
-#endif // USE(GLX)
+#endif // PLATFORM(X11)
#endif // RedirectedXCompositeWindow_h
diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
index 774939151..0a83827c7 100644
--- a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
+++ b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp
@@ -56,7 +56,7 @@ static void gtkStyleChangedCallback(GObject*, GParamSpec*)
{
StyleContextMap::const_iterator end = styleContextMap().end();
for (StyleContextMap::const_iterator iter = styleContextMap().begin(); iter != end; ++iter)
- gtk_style_context_invalidate(iter->second.get());
+ gtk_style_context_invalidate(iter->value.get());
Page::scheduleForcedStyleRecalcForAllPages();
}
@@ -79,7 +79,7 @@ static GtkStyleContext* getStyleContext(GType widgetType)
{
StyleContextMap::AddResult result = styleContextMap().add(widgetType, 0);
if (!result.isNewEntry)
- return result.iterator->second.get();
+ return result.iterator->value.get();
GtkWidgetPath* path = gtk_widget_path_new();
gtk_widget_path_append_type(path, widgetType);
@@ -111,7 +111,7 @@ static GtkStyleContext* getStyleContext(GType widgetType)
gtk_style_context_set_path(context.get(), path);
gtk_widget_path_free(path);
- result.iterator->second = context;
+ result.iterator->value = context;
return context.get();
}
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h
index 303d7599a..d0cc53b14 100644
--- a/Source/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h
@@ -177,10 +177,10 @@ namespace WebCore {
Vector<PixelData> m_backingStore;
PixelData* m_bytes; // The memory is backed by m_backingStore.
IntSize m_size;
- bool m_hasAlpha;
// FIXME: Do we need m_colorProfile anymore?
ColorProfile m_colorProfile;
#endif
+ bool m_hasAlpha;
IntRect m_originalFrameRect; // This will always just be the entire
// buffer except for GIF frames whose
// original rect was smaller than the
diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 0e4b53504..525f3a6f7 100644
--- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -612,6 +612,12 @@ bool JPEGImageDecoder::outputScanlines()
JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4);
if (info->out_color_space == JCS_RGB)
buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
+#if defined(TURBO_JPEG_RGB_SWIZZLE)
+ else if (info->out_color_space == JCS_EXT_RGBA)
+ buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
+ else if (info->out_color_space == JCS_EXT_BGRA)
+ buffer.setRGBA(x, destY, jsample[2], jsample[1], jsample[0], 0xFF);
+#endif
else if (info->out_color_space == JCS_CMYK) {
// Source is 'Inverted CMYK', output is RGB.
// See: http://www.easyrgb.com/math.php?MATH=M12#text12
diff --git a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
index 5cc132c4d..1fe7348ef 100644
--- a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
+++ b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
@@ -30,7 +30,8 @@
namespace WebCore {
ImageFrame::ImageFrame()
- : m_status(FrameEmpty)
+ : m_hasAlpha(false)
+ , m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
, m_premultiplyAlpha(true)
@@ -51,6 +52,9 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other)
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
setPremultiplyAlpha(other.premultiplyAlpha());
+ // Be sure that this is called after we've called setStatus(), since we
+ // look at our status to know what to do with the alpha value.
+ setHasAlpha(other.hasAlpha());
return *this;
}
@@ -67,6 +71,7 @@ void ImageFrame::clearPixelData()
void ImageFrame::zeroFillPixelData()
{
m_bitmap.bitmap().eraseARGB(0, 0, 0, 0);
+ m_hasAlpha = true;
}
bool ImageFrame::copyBitmapData(const ImageFrame& other)
@@ -99,12 +104,20 @@ NativeImagePtr ImageFrame::asNewNativeImage() const
bool ImageFrame::hasAlpha() const
{
- return !m_bitmap.bitmap().isOpaque();
+ return m_hasAlpha;
}
void ImageFrame::setHasAlpha(bool alpha)
{
- m_bitmap.bitmap().setIsOpaque(!alpha);
+ m_hasAlpha = alpha;
+
+ // If the frame is not fully loaded, there will be transparent pixels,
+ // so we can't tell skia we're opaque, even for image types that logically
+ // always are (e.g. jpeg).
+ bool isOpaque = !m_hasAlpha;
+ if (m_status != FrameComplete)
+ isOpaque = false;
+ m_bitmap.bitmap().setIsOpaque(isOpaque);
}
void ImageFrame::setColorProfile(const ColorProfile& colorProfile)
@@ -116,8 +129,10 @@ void ImageFrame::setColorProfile(const ColorProfile& colorProfile)
void ImageFrame::setStatus(FrameStatus status)
{
m_status = status;
- if (m_status == FrameComplete)
+ if (m_status == FrameComplete) {
+ m_bitmap.bitmap().setIsOpaque(!m_hasAlpha);
m_bitmap.setDataComplete(); // Tell the bitmap it's done.
+ }
}
int ImageFrame::width() const
diff --git a/Source/WebCore/platform/leveldb/LevelDBTransaction.cpp b/Source/WebCore/platform/leveldb/LevelDBTransaction.cpp
index 26580c210..8fe3fd08e 100644
--- a/Source/WebCore/platform/leveldb/LevelDBTransaction.cpp
+++ b/Source/WebCore/platform/leveldb/LevelDBTransaction.cpp
@@ -125,6 +125,12 @@ bool LevelDBTransaction::get(const LevelDBSlice& key, Vector<char>& value)
bool LevelDBTransaction::commit()
{
ASSERT(!m_finished);
+
+ if (m_tree.is_empty()) {
+ m_finished = true;
+ return true;
+ }
+
OwnPtr<LevelDBWriteBatch> writeBatch = LevelDBWriteBatch::create();
TreeType::Iterator iterator;
diff --git a/Source/WebCore/platform/mac/ClipboardMac.h b/Source/WebCore/platform/mac/ClipboardMac.h
index 75517c161..305a92ff9 100644
--- a/Source/WebCore/platform/mac/ClipboardMac.h
+++ b/Source/WebCore/platform/mac/ClipboardMac.h
@@ -62,7 +62,7 @@ public:
virtual bool hasData();
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
void setDragImage(CachedImage*, const IntPoint&);
diff --git a/Source/WebCore/platform/mac/ClipboardMac.mm b/Source/WebCore/platform/mac/ClipboardMac.mm
index 1af14df9c..bd8802044 100644
--- a/Source/WebCore/platform/mac/ClipboardMac.mm
+++ b/Source/WebCore/platform/mac/ClipboardMac.mm
@@ -65,6 +65,8 @@ ClipboardMac::ClipboardMac(ClipboardType clipboardType, const String& pasteboard
ClipboardMac::~ClipboardMac()
{
+ if (m_dragImage)
+ m_dragImage->removeClient(this);
}
bool ClipboardMac::hasData()
@@ -120,7 +122,7 @@ static String utiTypeFromCocoaType(const String& type)
return String();
}
-static void addHTMLClipboardTypesForCocoaType(HashSet<String>& resultTypes, const String& cocoaType, const String& pasteboardName)
+static void addHTMLClipboardTypesForCocoaType(ListHashSet<String>& resultTypes, const String& cocoaType, const String& pasteboardName)
{
// UTI may not do these right, so make sure we get the right, predictable result
if (cocoaType == String(NSStringPboardType)) {
@@ -282,10 +284,10 @@ bool ClipboardMac::setData(const String &type, const String &data)
return false;
}
-HashSet<String> ClipboardMac::types() const
+ListHashSet<String> ClipboardMac::types() const
{
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
- return HashSet<String>();
+ return ListHashSet<String>();
Vector<String> types;
platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName);
@@ -293,9 +295,9 @@ HashSet<String> ClipboardMac::types() const
// Enforce changeCount ourselves for security. We check after reading instead of before to be
// sure it doesn't change between our testing the change count and accessing the data.
if (m_changeCount != platformStrategies()->pasteboardStrategy()->changeCount(m_pasteboardName))
- return HashSet<String>();
+ return ListHashSet<String>();
- HashSet<String> result;
+ ListHashSet<String> result;
// FIXME: This loop could be split into two stages. One which adds all the HTML5 specified types
// and a second which adds all the extra types from the cocoa clipboard (which is Mac-only behavior).
for (size_t i = 0; i < types.size(); i++) {
diff --git a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h
index d4df7e60e..824f2ff8d 100644
--- a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h
+++ b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.h
@@ -39,6 +39,7 @@ public:
private:
GraphicsContext* m_savedGraphicsContext;
NSGraphicsContext* m_savedNSGraphicsContext;
+ bool m_didSetGraphicsContext;
#if USE(SKIA)
gfx::SkiaBitLocker m_skiaBitLocker;
#endif
diff --git a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm
index 5f1d07c67..f033df32c 100644
--- a/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm
+++ b/Source/WebCore/platform/mac/LocalCurrentGraphicsContext.mm
@@ -30,8 +30,9 @@
namespace WebCore {
LocalCurrentGraphicsContext::LocalCurrentGraphicsContext(GraphicsContext* graphicsContext)
+ : m_didSetGraphicsContext(false)
#if USE(SKIA)
- : m_skiaBitLocker(graphicsContext->platformContext()->canvas())
+ , m_skiaBitLocker(graphicsContext->platformContext()->canvas())
#endif
{
m_savedGraphicsContext = graphicsContext;
@@ -42,20 +43,21 @@ LocalCurrentGraphicsContext::LocalCurrentGraphicsContext(GraphicsContext* graphi
m_savedNSGraphicsContext = 0;
return;
}
-
+
m_savedNSGraphicsContext = [[NSGraphicsContext currentContext] retain];
NSGraphicsContext* newContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES];
[NSGraphicsContext setCurrentContext:newContext];
+ m_didSetGraphicsContext = true;
}
LocalCurrentGraphicsContext::~LocalCurrentGraphicsContext()
{
- m_savedGraphicsContext->restore();
-
- if (m_savedNSGraphicsContext) {
+ if (m_didSetGraphicsContext) {
[NSGraphicsContext setCurrentContext:m_savedNSGraphicsContext];
[m_savedNSGraphicsContext release];
}
+
+ m_savedGraphicsContext->restore();
}
CGContextRef LocalCurrentGraphicsContext::cgContext()
diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm
index 750130fc4..95af8f6c7 100644
--- a/Source/WebCore/platform/mac/PasteboardMac.mm
+++ b/Source/WebCore/platform/mac/PasteboardMac.mm
@@ -49,6 +49,7 @@
#import "MIMETypeRegistry.h"
#import "Page.h"
#import "RenderImage.h"
+#import "ResourceBuffer.h"
#import "Text.h"
#import "WebCoreNSStringExtras.h"
#import "WebNSAttributedStringExtras.h"
@@ -260,7 +261,7 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
static NSFileWrapper* fileWrapperForImage(CachedResource* resource, NSURL *url)
{
- SharedBuffer* coreData = resource->data();
+ ResourceBuffer* coreData = resource->resourceBuffer();
NSData *data = [[[NSData alloc] initWithBytes:coreData->data() length:coreData->size()] autorelease];
NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease];
String coreMIMEType = resource->response().mimeType();
diff --git a/Source/WebCore/platform/mac/ScrollbarThemeMac.mm b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm
index 96aa12a26..84fd0feb3 100644
--- a/Source/WebCore/platform/mac/ScrollbarThemeMac.mm
+++ b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm
@@ -86,8 +86,8 @@ static ScrollbarPainterMap* scrollbarMap()
return;
ScrollbarPainterMap::iterator end = scrollbarMap()->end();
for (ScrollbarPainterMap::iterator it = scrollbarMap()->begin(); it != end; ++it) {
- it->first->styleChanged();
- it->first->invalidate();
+ it->key->styleChanged();
+ it->key->invalidate();
}
}
@@ -477,6 +477,7 @@ void ScrollbarThemeMac::updateEnabledState(ScrollbarThemeClient* scrollbar)
[scrollbarMap()->get(scrollbar).get() setEnabled:scrollbar->enabled()];
}
+#if !PLATFORM(CHROMIUM)
static void scrollbarPainterPaint(ScrollbarPainter scrollbarPainter, bool enabled, double value, CGFloat proportion, CGRect frameRect)
{
[scrollbarPainter setEnabled:enabled];
@@ -494,7 +495,6 @@ static void scrollbarPainterPaint(ScrollbarPainter scrollbarPainter, bool enable
[scrollbarPainter drawKnob];
}
-#if !PLATFORM(CHROMIUM)
bool ScrollbarThemeMac::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* context, const IntRect& damageRect)
{
if (isScrollbarOverlayAPIAvailable()) {
diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.h b/Source/WebCore/platform/mac/WebCoreSystemInterface.h
index 940e4a625..c5df5d199 100644
--- a/Source/WebCore/platform/mac/WebCoreSystemInterface.h
+++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.h
@@ -120,6 +120,9 @@ typedef enum {
wkPatternTilingConstantSpacing
} wkPatternTiling;
extern void (*wkCGContextResetClip)(CGContextRef);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+extern bool (*wkCGContextDrawsWithCorrectShadowOffsets)(CGContextRef);
+#endif
extern CGPatternRef (*wkCGPatternCreateWithImageAndTransform)(CGImageRef, CGAffineTransform, int);
extern CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadStreamRef, void *),
void (*formFinalize)(CFReadStreamRef, void *),
@@ -232,6 +235,17 @@ extern int (*wkGetNSEventMomentumPhase)(NSEvent *);
extern CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+enum {
+ wkCTFontTransformApplyShaping = (1 << 0),
+ wkCTFontTransformApplyPositioning = (1 << 1)
+};
+
+typedef int wkCTFontTransformOptions;
+
+extern bool (*wkCTFontTransformGlyphs)(CTFontRef font, CGGlyph glyphs[], CGSize advances[], CFIndex count, wkCTFontTransformOptions options);
+#endif
+
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
extern CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options);
diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
index 379b6830e..a467a4b16 100644
--- a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
+++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
@@ -33,6 +33,9 @@ void (*wkCALayerEnumerateRectsBeingDrawnWithBlock)(CALayer *, CGContextRef conte
#endif
BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef);
void (*wkCGContextResetClip)(CGContextRef);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+bool (*wkCGContextDrawsWithCorrectShadowOffsets)(CGContextRef);
+#endif
CGPatternRef (*wkCGPatternCreateWithImageAndTransform)(CGImageRef, CGAffineTransform, int);
CFStringRef (*wkCopyCFLocalizationPreferredName)(CFStringRef);
NSString* (*wkCopyNSURLResponseStatusLine)(NSURLResponse*);
@@ -133,6 +136,10 @@ int (*wkGetNSEventMomentumPhase)(NSEvent *);
#endif
CTLineRef (*wkCreateCTLineWithUniCharProvider)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+bool (*wkCTFontTransformGlyphs)(CTFontRef font, CGGlyph glyphs[], CGSize advances[], CFIndex count, wkCTFontTransformOptions options);
+#endif
+
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
CTTypesetterRef (*wkCreateCTTypesetterWithUniCharProviderAndOptions)(const UniChar* (*provide)(CFIndex stringIndex, CFIndex* charCount, CFDictionaryRef* attributes, void*), void (*dispose)(const UniChar* chars, void*), void*, CFDictionaryRef options);
diff --git a/Source/WebCore/platform/mediastream/MediaConstraints.h b/Source/WebCore/platform/mediastream/MediaConstraints.h
index f285c579b..5141c228d 100644
--- a/Source/WebCore/platform/mediastream/MediaConstraints.h
+++ b/Source/WebCore/platform/mediastream/MediaConstraints.h
@@ -38,12 +38,23 @@
namespace WebCore {
+struct MediaConstraint {
+ MediaConstraint(String name, String value)
+ : m_name(name)
+ , m_value(value)
+ {
+ }
+
+ String m_name;
+ String m_value;
+};
+
class MediaConstraints : public RefCounted<MediaConstraints> {
public:
virtual ~MediaConstraints() { }
- virtual void getMandatoryConstraintNames(Vector<String>& names) const = 0;
- virtual void getOptionalConstraintNames(Vector<String>& names) const = 0;
+ virtual void getMandatoryConstraints(Vector<MediaConstraint>&) const = 0;
+ virtual void getOptionalConstraints(Vector<MediaConstraint>&) const = 0;
virtual bool getMandatoryConstraintValue(const String& name, String& value) const = 0;
virtual bool getOptionalConstraintValue(const String& name, String& value) const = 0;
diff --git a/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.cpp b/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.cpp
new file mode 100644
index 000000000..d2695b345
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "RTCDataChannelDescriptor.h"
+
+namespace WebCore {
+
+PassRefPtr<RTCDataChannelDescriptor> RTCDataChannelDescriptor::create(const String& label, bool reliable)
+{
+ return adoptRef(new RTCDataChannelDescriptor(label, reliable));
+}
+
+RTCDataChannelDescriptor::RTCDataChannelDescriptor(const String& label, bool reliable)
+ : m_label(label)
+ , m_reliable(reliable)
+ , m_readyState(ReadyStateConnecting)
+ , m_bufferedAmount(0)
+{
+}
+
+RTCDataChannelDescriptor::~RTCDataChannelDescriptor()
+{
+}
+
+void RTCDataChannelDescriptor::readyStateChanged(ReadyState readyState)
+{
+ ASSERT(m_readyState != ReadyStateClosed);
+ if (m_readyState != readyState && m_client) {
+ m_readyState = readyState;
+ m_client->readyStateChanged();
+ }
+}
+
+void RTCDataChannelDescriptor::dataArrived(const String& data)
+{
+ ASSERT(m_readyState != ReadyStateClosed);
+ if (m_client)
+ m_client->dataArrived(data);
+}
+
+void RTCDataChannelDescriptor::dataArrived(const char* data, size_t dataLength)
+{
+ ASSERT(m_readyState != ReadyStateClosed);
+ if (m_client)
+ m_client->dataArrived(data, dataLength);
+}
+
+void RTCDataChannelDescriptor::error()
+{
+ ASSERT(m_readyState != ReadyStateClosed);
+ if (m_client)
+ m_client->error();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.h b/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.h
new file mode 100644
index 000000000..eacb4ac3b
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RTCDataChannelDescriptor.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTCDataChannelDescriptor_h
+#define RTCDataChannelDescriptor_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class RTCDataChannelDescriptorClient {
+public:
+ virtual ~RTCDataChannelDescriptorClient() { }
+
+ virtual void readyStateChanged() = 0;
+ virtual void dataArrived(const String&) = 0;
+ virtual void dataArrived(const char*, size_t) = 0;
+ virtual void error() = 0;
+};
+
+class RTCDataChannelDescriptor : public RefCounted<RTCDataChannelDescriptor> {
+public:
+ class ExtraData : public RefCounted<ExtraData> {
+ public:
+ virtual ~ExtraData() { }
+ };
+
+ enum ReadyState {
+ ReadyStateConnecting = 0,
+ ReadyStateOpen = 1,
+ ReadyStateClosing = 2,
+ ReadyStateClosed = 3,
+ };
+
+ static PassRefPtr<RTCDataChannelDescriptor> create(const String& label, bool reliable);
+ virtual ~RTCDataChannelDescriptor();
+
+ RTCDataChannelDescriptorClient* client() const { return m_client; }
+ void setClient(RTCDataChannelDescriptorClient* client) { m_client = client; }
+
+ const String& label() const { return m_label; }
+ bool reliable() const { return m_reliable; }
+
+ ReadyState readyState() const { return m_readyState; }
+
+ unsigned long bufferedAmount() const { return m_bufferedAmount; }
+ void setBufferedAmount(unsigned long bufferedAmount) { m_bufferedAmount = bufferedAmount; }
+
+ void readyStateChanged(ReadyState);
+ void dataArrived(const String&);
+ void dataArrived(const char*, size_t);
+ void error();
+
+ PassRefPtr<ExtraData> extraData() const { return m_extraData; }
+ void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
+
+private:
+ RTCDataChannelDescriptor(const String& label, bool reliable);
+
+ RTCDataChannelDescriptorClient* m_client;
+ String m_label;
+ bool m_reliable;
+ ReadyState m_readyState;
+ unsigned long m_bufferedAmount;
+ RefPtr<ExtraData> m_extraData;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RTCDataChannelDescriptor_h
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp
index dfd5d18d4..8509f2e94 100644
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp
+++ b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp
@@ -59,8 +59,15 @@ public:
virtual bool addIceCandidate(PassRefPtr<RTCIceCandidateDescriptor>) OVERRIDE;
virtual bool addStream(PassRefPtr<MediaStreamDescriptor>, PassRefPtr<MediaConstraints>) OVERRIDE;
virtual void removeStream(PassRefPtr<MediaStreamDescriptor>) OVERRIDE;
+ virtual void getStats(PassRefPtr<RTCStatsRequest>) OVERRIDE;
virtual void stop() OVERRIDE;
+ // RTCDataChannel.
+ virtual bool openDataChannel(PassRefPtr<RTCDataChannelDescriptor>) OVERRIDE;
+ virtual bool sendStringData(PassRefPtr<RTCDataChannelDescriptor>, const String&) OVERRIDE;
+ virtual bool sendRawData(PassRefPtr<RTCDataChannelDescriptor>, const char*, size_t) OVERRIDE;
+ virtual void closeDataChannel(PassRefPtr<RTCDataChannelDescriptor>) OVERRIDE;
+
private:
RTCPeerConnectionHandlerClient* m_client;
};
@@ -130,10 +137,33 @@ bool RTCPeerConnectionHandlerDummy::addIceCandidate(PassRefPtr<RTCIceCandidateDe
return false;
}
+void RTCPeerConnectionHandlerDummy::getStats(PassRefPtr<RTCStatsRequest>)
+{
+}
+
void RTCPeerConnectionHandlerDummy::stop()
{
}
+bool RTCPeerConnectionHandlerDummy::openDataChannel(PassRefPtr<RTCDataChannelDescriptor>)
+{
+ return false;
+}
+
+bool RTCPeerConnectionHandlerDummy::sendStringData(PassRefPtr<RTCDataChannelDescriptor>, const String&)
+{
+ return false;
+}
+
+bool RTCPeerConnectionHandlerDummy::sendRawData(PassRefPtr<RTCDataChannelDescriptor>, const char*, size_t)
+{
+ return false;
+}
+
+void RTCPeerConnectionHandlerDummy::closeDataChannel(PassRefPtr<RTCDataChannelDescriptor>)
+{
+}
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h
index 18021c582..fba45887e 100644
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h
+++ b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h
@@ -41,10 +41,12 @@ namespace WebCore {
class MediaConstraints;
class RTCConfiguration;
+class RTCDataChannelDescriptor;
class RTCIceCandidateDescriptor;
class RTCPeerConnectionHandlerClient;
class RTCSessionDescriptionDescriptor;
class RTCSessionDescriptionRequest;
+class RTCStatsRequest;
class RTCVoidRequest;
class RTCPeerConnectionHandler {
@@ -64,8 +66,15 @@ public:
virtual bool addIceCandidate(PassRefPtr<RTCIceCandidateDescriptor>) = 0;
virtual bool addStream(PassRefPtr<MediaStreamDescriptor>, PassRefPtr<MediaConstraints>) = 0;
virtual void removeStream(PassRefPtr<MediaStreamDescriptor>) = 0;
+ virtual void getStats(PassRefPtr<RTCStatsRequest>) = 0;
virtual void stop() = 0;
+ // RTCDataChannel.
+ virtual bool openDataChannel(PassRefPtr<RTCDataChannelDescriptor>) = 0;
+ virtual bool sendStringData(PassRefPtr<RTCDataChannelDescriptor>, const String&) = 0;
+ virtual bool sendRawData(PassRefPtr<RTCDataChannelDescriptor>, const char*, size_t) = 0;
+ virtual void closeDataChannel(PassRefPtr<RTCDataChannelDescriptor>) = 0;
+
protected:
RTCPeerConnectionHandler() { }
};
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
index 33b904260..389c8671b 100644
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
+++ b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
@@ -38,6 +38,7 @@
namespace WebCore {
class MediaStreamDescriptor;
+class RTCDataChannelDescriptor;
class RTCIceCandidateDescriptor;
class RTCPeerConnectionHandlerClient {
@@ -69,6 +70,9 @@ public:
virtual void didChangeIceState(IceState) = 0;
virtual void didAddRemoteStream(PassRefPtr<MediaStreamDescriptor>) = 0;
virtual void didRemoveRemoteStream(MediaStreamDescriptor*) = 0;
+
+ // RTCDataChannel.
+ virtual void didAddRemoteDataChannel(PassRefPtr<RTCDataChannelDescriptor>) = 0;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/mediastream/RTCStatsRequest.h b/Source/WebCore/platform/mediastream/RTCStatsRequest.h
new file mode 100644
index 000000000..6b9096829
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RTCStatsRequest.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. 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.
+ */
+
+#ifndef RTCStatsRequest_h
+#define RTCStatsRequest_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MediaStreamComponent;
+class MediaStreamDescriptor;
+class RTCStatsResponseBase;
+
+class RTCStatsRequest : public RefCounted<RTCStatsRequest> {
+public:
+ virtual ~RTCStatsRequest() { }
+
+ virtual PassRefPtr<RTCStatsResponseBase> createResponse() = 0;
+ virtual bool hasSelector() = 0;
+ virtual MediaStreamDescriptor* stream() = 0;
+ virtual MediaStreamComponent* component() = 0;
+ virtual void requestSucceeded(PassRefPtr<RTCStatsResponseBase>) = 0;
+
+protected:
+ RTCStatsRequest() { }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RTCStatsRequest_h
diff --git a/Source/WebCore/platform/mediastream/RTCStatsResponseBase.h b/Source/WebCore/platform/mediastream/RTCStatsResponseBase.h
new file mode 100644
index 000000000..91cbfa686
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RTCStatsResponseBase.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RTCStatsResponseBase_h
+#define RTCStatsResponseBase_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class RTCStatsResponseBase : public RefCounted<RTCStatsResponseBase> {
+public:
+ virtual ~RTCStatsResponseBase() { }
+
+ virtual size_t addReport() = 0;
+ virtual void addElement(size_t report, bool isLocal, double timestamp) = 0;
+ virtual void addStatistic(size_t report, bool isLocal, String name, String value) = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RTCStatsResponseBase_h
+
diff --git a/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.cpp b/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.cpp
index 08a0373e0..61fb1c48a 100644
--- a/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.cpp
+++ b/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.cpp
@@ -36,23 +36,32 @@
#include "MediaConstraints.h"
#include "RTCConfiguration.h"
+#include "RTCDataChannelDescriptor.h"
#include "RTCIceCandidateDescriptor.h"
#include "RTCPeerConnectionHandlerClient.h"
#include "RTCSessionDescriptionDescriptor.h"
#include "RTCSessionDescriptionRequest.h"
+#include "RTCStatsRequest.h"
#include "RTCVoidRequest.h"
#include <public/Platform.h>
#include <public/WebMediaConstraints.h>
#include <public/WebMediaStreamDescriptor.h>
#include <public/WebRTCConfiguration.h>
+#include <public/WebRTCDataChannel.h>
#include <public/WebRTCICECandidate.h>
#include <public/WebRTCSessionDescription.h>
#include <public/WebRTCSessionDescriptionRequest.h>
+#include <public/WebRTCStatsRequest.h>
#include <public/WebRTCVoidRequest.h>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
+WebKit::WebRTCPeerConnectionHandler* RTCPeerConnectionHandlerChromium::toWebRTCPeerConnectionHandler(RTCPeerConnectionHandler* handler)
+{
+ return static_cast<RTCPeerConnectionHandlerChromium*>(handler)->m_webHandler.get();
+}
+
PassOwnPtr<RTCPeerConnectionHandler> RTCPeerConnectionHandler::create(RTCPeerConnectionHandlerClient* client)
{
return adoptPtr(new RTCPeerConnectionHandlerChromium(client));
@@ -62,6 +71,7 @@ RTCPeerConnectionHandlerChromium::RTCPeerConnectionHandlerChromium(RTCPeerConnec
: m_client(client)
{
ASSERT(m_client);
+ m_webHandler = adoptPtr(WebKit::Platform::current()->createRTCPeerConnectionHandler(this));
}
RTCPeerConnectionHandlerChromium::~RTCPeerConnectionHandlerChromium()
@@ -70,8 +80,10 @@ RTCPeerConnectionHandlerChromium::~RTCPeerConnectionHandlerChromium()
bool RTCPeerConnectionHandlerChromium::initialize(PassRefPtr<RTCConfiguration> configuration, PassRefPtr<MediaConstraints> constraints)
{
- m_webHandler = adoptPtr(WebKit::Platform::current()->createRTCPeerConnectionHandler(this));
- return m_webHandler ? m_webHandler->initialize(configuration, constraints) : false;
+ if (!m_webHandler)
+ return false;
+
+ return m_webHandler->initialize(configuration, constraints);
}
void RTCPeerConnectionHandlerChromium::createOffer(PassRefPtr<RTCSessionDescriptionRequest> request, PassRefPtr<MediaConstraints> constraints)
@@ -156,6 +168,46 @@ void RTCPeerConnectionHandlerChromium::removeStream(PassRefPtr<MediaStreamDescri
m_webHandler->removeStream(mediaStream);
}
+void RTCPeerConnectionHandlerChromium::getStats(PassRefPtr<RTCStatsRequest> request)
+{
+ if (!m_webHandler)
+ return;
+
+ m_webHandler->getStats(request);
+}
+
+bool RTCPeerConnectionHandlerChromium::openDataChannel(PassRefPtr<RTCDataChannelDescriptor> dataChannel)
+{
+ if (!m_webHandler)
+ return false;
+
+ return m_webHandler->openDataChannel(dataChannel);
+}
+
+bool RTCPeerConnectionHandlerChromium::sendStringData(PassRefPtr<RTCDataChannelDescriptor> dataChannel, const String& data)
+{
+ if (!m_webHandler)
+ return false;
+
+ return m_webHandler->sendStringData(dataChannel, data);
+}
+
+bool RTCPeerConnectionHandlerChromium::sendRawData(PassRefPtr<RTCDataChannelDescriptor> dataChannel, const char* data, size_t dataLength)
+{
+ if (!m_webHandler)
+ return false;
+
+ return m_webHandler->sendRawData(dataChannel, data, dataLength);
+}
+
+void RTCPeerConnectionHandlerChromium::closeDataChannel(PassRefPtr<RTCDataChannelDescriptor> dataChannel)
+{
+ if (!m_webHandler)
+ return;
+
+ return m_webHandler->closeDataChannel(dataChannel);
+}
+
void RTCPeerConnectionHandlerChromium::stop()
{
if (!m_webHandler)
diff --git a/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.h b/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.h
index 5f6947174..6da11957a 100644
--- a/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.h
+++ b/Source/WebCore/platform/mediastream/chromium/RTCPeerConnectionHandlerChromium.h
@@ -49,7 +49,7 @@ namespace WebCore {
class RTCPeerConnectionHandlerChromium : public RTCPeerConnectionHandler, public WebKit::WebRTCPeerConnectionHandlerClient {
public:
- RTCPeerConnectionHandlerChromium(RTCPeerConnectionHandlerClient*);
+ explicit RTCPeerConnectionHandlerChromium(RTCPeerConnectionHandlerClient*);
virtual ~RTCPeerConnectionHandlerChromium();
virtual bool initialize(PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>) OVERRIDE;
@@ -64,8 +64,14 @@ public:
virtual bool addIceCandidate(PassRefPtr<RTCIceCandidateDescriptor>) OVERRIDE;
virtual bool addStream(PassRefPtr<MediaStreamDescriptor>, PassRefPtr<MediaConstraints>) OVERRIDE;
virtual void removeStream(PassRefPtr<MediaStreamDescriptor>) OVERRIDE;
+ virtual void getStats(PassRefPtr<RTCStatsRequest>) OVERRIDE;
virtual void stop() OVERRIDE;
+ virtual bool openDataChannel(PassRefPtr<RTCDataChannelDescriptor>) OVERRIDE;
+ virtual bool sendStringData(PassRefPtr<RTCDataChannelDescriptor>, const String&) OVERRIDE;
+ virtual bool sendRawData(PassRefPtr<RTCDataChannelDescriptor>, const char*, size_t) OVERRIDE;
+ virtual void closeDataChannel(PassRefPtr<RTCDataChannelDescriptor>) OVERRIDE;
+
// WebKit::WebRTCPeerConnectionHandlerClient implementation.
virtual void negotiationNeeded() OVERRIDE;
virtual void didGenerateICECandidate(const WebKit::WebRTCICECandidate&) OVERRIDE;
@@ -74,6 +80,8 @@ public:
virtual void didAddRemoteStream(const WebKit::WebMediaStreamDescriptor&) OVERRIDE;
virtual void didRemoveRemoteStream(const WebKit::WebMediaStreamDescriptor&) OVERRIDE;
+ static WebKit::WebRTCPeerConnectionHandler* toWebRTCPeerConnectionHandler(RTCPeerConnectionHandler*);
+
private:
OwnPtr<WebKit::WebRTCPeerConnectionHandler> m_webHandler;
RTCPeerConnectionHandlerClient* m_client;
diff --git a/Source/WebCore/platform/network/CredentialStorage.cpp b/Source/WebCore/platform/network/CredentialStorage.cpp
index f624d4fcb..8b5ac478b 100644
--- a/Source/WebCore/platform/network/CredentialStorage.cpp
+++ b/Source/WebCore/platform/network/CredentialStorage.cpp
@@ -147,7 +147,7 @@ bool CredentialStorage::set(const Credential& credential, const KURL& url)
if (iter == pathToDefaultProtectionSpaceMap().end())
return false;
ASSERT(originsWithCredentials().contains(originStringFromURL(url)));
- protectionSpaceToCredentialMap().set(iter->second, credential);
+ protectionSpaceToCredentialMap().set(iter->value, credential);
return true;
}
@@ -156,7 +156,7 @@ Credential CredentialStorage::get(const KURL& url)
PathToDefaultProtectionSpaceMap::iterator iter = findDefaultProtectionSpaceForURL(url);
if (iter == pathToDefaultProtectionSpaceMap().end())
return Credential();
- return protectionSpaceToCredentialMap().get(iter->second);
+ return protectionSpaceToCredentialMap().get(iter->value);
}
void CredentialStorage::setPrivateMode(bool mode)
diff --git a/Source/WebCore/platform/network/DataURL.cpp b/Source/WebCore/platform/network/DataURL.cpp
index aae525c25..7767fe264 100644
--- a/Source/WebCore/platform/network/DataURL.cpp
+++ b/Source/WebCore/platform/network/DataURL.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
void handleDataURL(ResourceHandle* handle)
{
- ASSERT(handle->firstRequest().url().protocolIs("data"));
+ ASSERT(handle->firstRequest().url().protocolIsData());
String url = handle->firstRequest().url().string();
int index = url.find(',');
diff --git a/Source/WebCore/platform/network/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
index 50091e19d..defe1ae84 100644
--- a/Source/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/Source/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -52,7 +52,7 @@ PassOwnPtr<CrossThreadHTTPHeaderMapData> HTTPHeaderMap::copyData() const
HTTPHeaderMap::const_iterator end_it = end();
for (HTTPHeaderMap::const_iterator it = begin(); it != end_it; ++it) {
- data->append(make_pair(it->first.string().isolatedCopy(), it->second.isolatedCopy()));
+ data->append(make_pair(it->key.string().isolatedCopy(), it->value.isolatedCopy()));
}
return data.release();
}
@@ -100,7 +100,7 @@ String HTTPHeaderMap::get(const char* name) const
const_iterator i = find<const char*, CaseFoldingCStringTranslator>(name);
if (i == end())
return String();
- return i->second;
+ return i->value;
}
bool HTTPHeaderMap::contains(const char* name) const
diff --git a/Source/WebCore/platform/network/MIMEHeader.cpp b/Source/WebCore/platform/network/MIMEHeader.cpp
index 5d6b858f4..f4e3ebf67 100644
--- a/Source/WebCore/platform/network/MIMEHeader.cpp
+++ b/Source/WebCore/platform/network/MIMEHeader.cpp
@@ -86,7 +86,7 @@ PassRefPtr<MIMEHeader> MIMEHeader::parseHeader(SharedBufferChunkReader* buffer)
KeyValueMap::iterator mimeParametersIterator = keyValuePairs.find("content-type");
if (mimeParametersIterator != keyValuePairs.end()) {
// FIXME: make ContentTypeParser more flexible so we don't have to synthesize the "Content-Type:".
- ContentTypeParser contentTypeParser(makeString("Content-Type:", mimeParametersIterator->second));
+ ContentTypeParser contentTypeParser(makeString("Content-Type:", mimeParametersIterator->value));
mimeHeader->m_contentType = contentTypeParser.mimeType();
if (!mimeHeader->isMultipart())
mimeHeader->m_charset = contentTypeParser.charset().stripWhiteSpace();
@@ -105,11 +105,11 @@ PassRefPtr<MIMEHeader> MIMEHeader::parseHeader(SharedBufferChunkReader* buffer)
mimeParametersIterator = keyValuePairs.find("content-transfer-encoding");
if (mimeParametersIterator != keyValuePairs.end())
- mimeHeader->m_contentTransferEncoding = parseContentTransferEncoding(mimeParametersIterator->second);
+ mimeHeader->m_contentTransferEncoding = parseContentTransferEncoding(mimeParametersIterator->value);
mimeParametersIterator = keyValuePairs.find("content-location");
if (mimeParametersIterator != keyValuePairs.end())
- mimeHeader->m_contentLocation = mimeParametersIterator->second;
+ mimeHeader->m_contentLocation = mimeParametersIterator->value;
return mimeHeader.release();
}
diff --git a/Source/WebCore/platform/network/NetworkingContext.h b/Source/WebCore/platform/network/NetworkingContext.h
index 046085c2f..e4c2daf94 100644
--- a/Source/WebCore/platform/network/NetworkingContext.h
+++ b/Source/WebCore/platform/network/NetworkingContext.h
@@ -72,6 +72,7 @@ public:
#if USE(SOUP)
virtual SoupSession* soupSession() const = 0;
+ virtual uint64_t initiatingPageID() const = 0;
#endif
protected:
diff --git a/Source/WebCore/platform/network/ResourceHandle.cpp b/Source/WebCore/platform/network/ResourceHandle.cpp
index 7ddc47e4e..6d12f9d89 100644
--- a/Source/WebCore/platform/network/ResourceHandle.cpp
+++ b/Source/WebCore/platform/network/ResourceHandle.cpp
@@ -71,7 +71,7 @@ PassRefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, co
BuiltinResourceHandleConstructorMap::iterator protocolMapItem = builtinResourceHandleConstructorMap().find(request.url().protocol());
if (protocolMapItem != builtinResourceHandleConstructorMap().end())
- return protocolMapItem->second(request, client);
+ return protocolMapItem->value(request, client);
RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff)));
diff --git a/Source/WebCore/platform/network/ResourceHandle.h b/Source/WebCore/platform/network/ResourceHandle.h
index fbea7c92a..b9bf34feb 100644
--- a/Source/WebCore/platform/network/ResourceHandle.h
+++ b/Source/WebCore/platform/network/ResourceHandle.h
@@ -34,6 +34,7 @@
#if USE(SOUP)
typedef struct _SoupSession SoupSession;
+typedef struct _SoupRequest SoupRequest;
#endif
#if USE(CF)
@@ -167,7 +168,9 @@ public:
#endif
#if USE(SOUP)
+ void sendPendingRequest();
static SoupSession* defaultSession();
+ static uint64_t getSoupRequestInitiaingPageID(SoupRequest*);
static void setHostAllowsAnyHTTPSCertificate(const String&);
static void setClientCertificate(const String& host, GTlsCertificate*);
static void setIgnoreSSLErrors(bool);
diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h
index ecf648fce..63df28245 100644
--- a/Source/WebCore/platform/network/ResourceHandleInternal.h
+++ b/Source/WebCore/platform/network/ResourceHandleInternal.h
@@ -187,11 +187,13 @@ namespace WebCore {
GRefPtr<GInputStream> m_inputStream;
GRefPtr<GCancellable> m_cancellable;
GRefPtr<GAsyncResult> m_deferredResult;
+ GRefPtr<GSource> m_timeoutSource;
char* m_buffer;
unsigned long m_bodySize;
unsigned long m_bodyDataSent;
RefPtr<NetworkingContext> m_context;
SoupSession* soupSession();
+ uint64_t initiatingPageID();
#endif
#if PLATFORM(QT)
QNetworkReplyHandler* m_job;
diff --git a/Source/WebCore/platform/network/ResourceLoadTiming.cpp b/Source/WebCore/platform/network/ResourceLoadTiming.cpp
index 5d9da48a3..e33439581 100644
--- a/Source/WebCore/platform/network/ResourceLoadTiming.cpp
+++ b/Source/WebCore/platform/network/ResourceLoadTiming.cpp
@@ -26,16 +26,11 @@
#include "config.h"
#include "ResourceLoadTiming.h"
-#include "DocumentLoadTiming.h"
-
namespace WebCore {
-double ResourceLoadTiming::convertResourceLoadTimeToDocumentTime(const DocumentLoadTiming* documentTiming, int deltaMilliseconds) const
+double ResourceLoadTiming::convertResourceLoadTimeToMonotonicTime(int deltaMilliseconds) const
{
- if (!documentTiming)
- return 0.0;
-
- return documentTiming->convertMonotonicTimeToDocumentTime(requestTime + deltaMilliseconds / 1000.0);
+ return requestTime + deltaMilliseconds / 1000.0;
}
}
diff --git a/Source/WebCore/platform/network/ResourceLoadTiming.h b/Source/WebCore/platform/network/ResourceLoadTiming.h
index 94c55d9ba..2a395ef7c 100644
--- a/Source/WebCore/platform/network/ResourceLoadTiming.h
+++ b/Source/WebCore/platform/network/ResourceLoadTiming.h
@@ -85,7 +85,7 @@ public:
// recorded using monotonicallyIncreasingTime(). When a time needs to be presented to Javascript, we build a pseudo-walltime
// using the following equation:
// pseudo time = document wall reference + (resource request time - document monotonic reference) + deltaMilliseconds / 1000.0.
- double convertResourceLoadTimeToDocumentTime(const DocumentLoadTiming* documentTiming, int deltaMilliseconds) const;
+ double convertResourceLoadTimeToMonotonicTime(int deltaMilliseconds) const;
double requestTime; // monotonicallyIncreasingTime() when the port started handling this request.
int proxyStart; // The rest of these are millisecond deltas, using monotonicallyIncreasingTime(), from requestTime.
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.cpp b/Source/WebCore/platform/network/ResourceRequestBase.cpp
index 303deaa9c..afcb243c6 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/Source/WebCore/platform/network/ResourceRequestBase.cpp
@@ -28,16 +28,18 @@
#include "PlatformMemoryInstrumentation.h"
#include "ResourceRequest.h"
+#include <wtf/MemoryInstrumentationHashMap.h>
#include <wtf/MemoryInstrumentationVector.h>
using namespace std;
namespace WebCore {
-#if !PLATFORM(MAC) || USE(CFNETWORK)
+#if !USE(SOUP) && (!PLATFORM(MAC) || USE(CFNETWORK))
double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX;
#else
// Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval().
+// For libsoup the timeout enabled with integer milliseconds. We set 0 as the default value to avoid integer overflow.
double ResourceRequestBase::s_defaultTimeoutInterval = 0;
#endif
@@ -375,7 +377,7 @@ void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const Str
updateResourceRequest();
HTTPHeaderMap::AddResult result = m_httpHeaderFields.add(name, value);
if (!result.isNewEntry)
- result.iterator->second = result.iterator->second + ',' + value;
+ result.iterator->value = result.iterator->value + ',' + value;
if (url().protocolIsInHTTPFamily())
m_platformRequestUpdated = false;
@@ -385,7 +387,7 @@ void ResourceRequestBase::addHTTPHeaderFields(const HTTPHeaderMap& headerFields)
{
HTTPHeaderMap::const_iterator end = headerFields.end();
for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it)
- addHTTPHeaderField(it->first, it->second);
+ addHTTPHeaderField(it->key, it->value);
}
bool equalIgnoringHeaderFields(const ResourceRequestBase& a, const ResourceRequestBase& b)
@@ -451,8 +453,7 @@ void ResourceRequestBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
info.addMember(m_url);
info.addMember(m_firstPartyForCookies);
info.addMember(m_httpMethod);
- info.addHashMap(m_httpHeaderFields);
- info.addInstrumentedMapEntries(m_httpHeaderFields);
+ info.addMember(m_httpHeaderFields);
info.addMember(m_responseContentDispositionEncodingFallbackArray);
info.addMember(m_httpBody);
}
diff --git a/Source/WebCore/platform/network/ResourceResponseBase.cpp b/Source/WebCore/platform/network/ResourceResponseBase.cpp
index 2521fb12e..48568ef6f 100644
--- a/Source/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/Source/WebCore/platform/network/ResourceResponseBase.cpp
@@ -32,6 +32,7 @@
#include "ResourceResponse.h"
#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
+#include <wtf/MemoryInstrumentationHashMap.h>
#include <wtf/StdLibExtras.h>
using namespace std;
@@ -576,8 +577,7 @@ void ResourceResponseBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo)
info.addMember(m_textEncodingName);
info.addMember(m_suggestedFilename);
info.addMember(m_httpStatusText);
- info.addHashMap(m_httpHeaderFields);
- info.addInstrumentedMapEntries(m_httpHeaderFields);
+ info.addMember(m_httpHeaderFields);
info.addMember(m_resourceLoadTiming);
info.addMember(m_resourceLoadInfo);
}
diff --git a/Source/WebCore/platform/network/blackberry/DNSBlackBerry.cpp b/Source/WebCore/platform/network/blackberry/DNSBlackBerry.cpp
index 69bd82d08..2977b9846 100644
--- a/Source/WebCore/platform/network/blackberry/DNSBlackBerry.cpp
+++ b/Source/WebCore/platform/network/blackberry/DNSBlackBerry.cpp
@@ -31,7 +31,7 @@ void prefetchDNS(const String& host)
{
if (host.isEmpty())
return;
- BlackBerry::Platform::prefetchDNS(host.latin1().data());
+ BlackBerry::Platform::prefetchDNS(host);
}
}
diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
index b1551783f..720ba1339 100644
--- a/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
+++ b/Source/WebCore/platform/network/blackberry/NetworkJob.cpp
@@ -19,6 +19,7 @@
#include "config.h"
#include "NetworkJob.h"
+#include "AuthenticationChallengeManager.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "CookieManager.h"
@@ -84,9 +85,16 @@ NetworkJob::NetworkJob()
, m_deferredData(*this)
, m_deferLoadingCount(0)
, m_frame(0)
+ , m_isAuthenticationChallenging(false)
{
}
+NetworkJob::~NetworkJob()
+{
+ if (m_isAuthenticationChallenging)
+ AuthenticationChallengeManager::instance()->cancelAuthenticationChallenge(this);
+}
+
bool NetworkJob::initialize(int playerId,
const String& pageGroupName,
const KURL& url,
@@ -122,14 +130,12 @@ bool NetworkJob::initialize(int playerId,
// We don't need to explicitly call notifyHeaderReceived, as the Content-Type
// will ultimately get parsed when sendResponseIfNeeded gets called.
if (!request.getOverrideContentType().empty()) {
- m_contentType = String(request.getOverrideContentType().c_str());
+ m_contentType = String(request.getOverrideContentType());
m_isOverrideContentType = true;
}
- if (!request.getSuggestedSaveName().empty()) {
- m_contentDisposition = "filename=";
- m_contentDisposition += request.getSuggestedSaveName().c_str();
- }
+ if (!request.getSuggestedSaveName().empty())
+ m_contentDisposition = "filename=" + String(request.getSuggestedSaveName());
BlackBerry::Platform::FilterStream* wrappedStream = m_streamFactory->createNetworkStream(request, m_playerId);
if (!wrappedStream)
@@ -167,7 +173,7 @@ void NetworkJob::updateDeferLoadingCount(int delta)
}
}
-void NetworkJob::notifyStatusReceived(int status, const char* message)
+void NetworkJob::notifyStatusReceived(int status, const BlackBerry::Platform::String& message)
{
if (shouldDeferLoading())
m_deferredData.deferOpen(status, message);
@@ -197,10 +203,8 @@ void NetworkJob::handleNotifyStatusReceived(int status, const String& message)
m_response.setHTTPStatusText(message);
- if (isUnauthorized(m_extendedStatusCode)) {
+ if (isUnauthorized(m_extendedStatusCode))
purgeCredentials();
- BlackBerry::Platform::log(BlackBerry::Platform::LogLevelCritical, "Authentication failed, purge the stored credentials for this site.");
- }
}
void NetworkJob::notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::HeaderList& headers)
@@ -208,9 +212,9 @@ void NetworkJob::notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::Hea
BlackBerry::Platform::NetworkRequest::HeaderList::const_iterator endIt = headers.end();
for (BlackBerry::Platform::NetworkRequest::HeaderList::const_iterator it = headers.begin(); it != endIt; ++it) {
if (shouldDeferLoading())
- m_deferredData.deferHeaderReceived(it->first.c_str(), it->second.c_str());
+ m_deferredData.deferHeaderReceived(it->first, it->second);
else {
- String keyString(it->first.c_str());
+ String keyString(it->first);
String valueString;
if (equalIgnoringCase(keyString, "Location")) {
// Location, like all headers, is supposed to be Latin-1. But some sites (wikipedia) send it in UTF-8.
@@ -221,11 +225,11 @@ void NetworkJob::notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::Hea
// FIXME: maybe we should do this with other headers?
// Skip it for now - we don't want to rewrite random bytes unless we're sure. (Definitely don't want to
// rewrite cookies, for instance.) Needs more investigation.
- valueString = String::fromUTF8(it->second.c_str());
+ valueString = it->second;
if (valueString.isNull())
- valueString = it->second.c_str();
+ valueString = it->second;
} else
- valueString = it->second.c_str();
+ valueString = it->second;
handleNotifyHeaderReceived(keyString, valueString);
}
@@ -246,6 +250,10 @@ void NetworkJob::notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthTy
ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP;
ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault;
+
+ if (m_response.url().protocolIs("https"))
+ serverType = ProtectionSpaceServerHTTPS;
+
switch (authType) {
case NetworkRequest::AuthHTTPBasic:
scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic;
@@ -260,10 +268,16 @@ void NetworkJob::notifyAuthReceived(BlackBerry::Platform::NetworkRequest::AuthTy
scheme = ProtectionSpaceAuthenticationSchemeNTLM;
break;
case NetworkRequest::AuthFTP:
- serverType = ProtectionSpaceServerFTP;
+ if (m_response.url().protocolIs("ftps"))
+ serverType = ProtectionSpaceServerFTPS;
+ else
+ serverType = ProtectionSpaceServerFTP;
break;
case NetworkRequest::AuthProxy:
- serverType = ProtectionSpaceProxyHTTP;
+ if (m_response.url().protocolIs("https"))
+ serverType = ProtectionSpaceProxyHTTPS;
+ else
+ serverType = ProtectionSpaceProxyHTTP;
break;
case NetworkRequest::AuthNone:
default:
@@ -478,10 +492,11 @@ void NetworkJob::handleNotifyClose(int status)
#ifndef NDEBUG
m_isRunning = false;
#endif
+
if (!m_cancelled) {
if (!m_statusReceived) {
// Connection failed before sending notifyStatusReceived: use generic NetworkError.
- notifyStatusReceived(BlackBerry::Platform::FilterStream::StatusNetworkError, 0);
+ notifyStatusReceived(BlackBerry::Platform::FilterStream::StatusNetworkError, BlackBerry::Platform::String::emptyString());
}
if (shouldReleaseClientResource()) {
@@ -489,6 +504,7 @@ void NetworkJob::handleNotifyClose(int status)
m_extendedStatusCode = BlackBerry::Platform::FilterStream::StatusTooManyRedirects;
sendResponseIfNeeded();
+
if (isClientAvailable()) {
if (isError(status))
m_extendedStatusCode = status;
@@ -514,7 +530,7 @@ void NetworkJob::handleNotifyClose(int status)
bool NetworkJob::shouldReleaseClientResource()
{
- if ((m_needsRetryAsFTPDirectory && retryAsFTPDirectory()) || (isRedirect(m_extendedStatusCode) && handleRedirect()) || m_newJobWithCredentialsStarted)
+ if ((m_needsRetryAsFTPDirectory && retryAsFTPDirectory()) || (isRedirect(m_extendedStatusCode) && handleRedirect()) || m_newJobWithCredentialsStarted || m_isAuthenticationChallenging)
return false;
return true;
}
@@ -690,7 +706,10 @@ bool NetworkJob::handleFTPHeader(const String& header)
break;
case 530:
purgeCredentials();
- sendRequestWithCredentials(ProtectionSpaceServerFTP, ProtectionSpaceAuthenticationSchemeDefault, "ftp");
+ if (m_response.url().protocolIs("ftps"))
+ sendRequestWithCredentials(ProtectionSpaceServerFTPS, ProtectionSpaceAuthenticationSchemeDefault, "ftp");
+ else
+ sendRequestWithCredentials(ProtectionSpaceServerFTP, ProtectionSpaceAuthenticationSchemeDefault, "ftp");
break;
case 230:
storeCredentials();
@@ -719,9 +738,20 @@ bool NetworkJob::sendRequestWithCredentials(ProtectionSpaceServerType type, Prot
String host;
int port;
- if (type == ProtectionSpaceProxyHTTP) {
- String proxyAddress = String(BlackBerry::Platform::Settings::instance()->proxyAddress(newURL.string().ascii().data()).c_str());
- KURL proxyURL(KURL(), proxyAddress);
+ if (type == ProtectionSpaceProxyHTTP || type == ProtectionSpaceProxyHTTPS) {
+ // proxyAddress returns host:port, without a protocol. KURL can't parse this, so stick http
+ // on the front.
+ // (We could split into host and port by hand, but that gets hard to parse with IPv6 urls,
+ // so better to reuse KURL's parsing.)
+ StringBuilder proxyAddress;
+
+ if (type == ProtectionSpaceProxyHTTP)
+ proxyAddress.append("http://");
+ else
+ proxyAddress.append("https://");
+
+ proxyAddress.append(BlackBerry::Platform::Settings::instance()->proxyAddress(newURL.string()));
+ KURL proxyURL(KURL(), proxyAddress.toString());
host = proxyURL.host();
port = proxyURL.port();
} else {
@@ -754,29 +784,39 @@ bool NetworkJob::sendRequestWithCredentials(ProtectionSpaceServerType type, Prot
String username;
String password;
- if (type == ProtectionSpaceProxyHTTP) {
- username = String(BlackBerry::Platform::Settings::instance()->proxyUsername().c_str());
- password = String(BlackBerry::Platform::Settings::instance()->proxyPassword().c_str());
+ if (type == ProtectionSpaceProxyHTTP || type == ProtectionSpaceProxyHTTPS) {
+ username = String(BlackBerry::Platform::Settings::instance()->proxyUsername());
+ password = String(BlackBerry::Platform::Settings::instance()->proxyPassword());
+ } else {
+ username = m_handle->getInternal()->m_user;
+ password = m_handle->getInternal()->m_pass;
}
- if (username.isEmpty() || password.isEmpty()) {
- // Before asking the user for credentials, we check if the URL contains that.
- if (!m_handle->getInternal()->m_user.isEmpty() && !m_handle->getInternal()->m_pass.isEmpty()) {
- username = m_handle->getInternal()->m_user;
- password = m_handle->getInternal()->m_pass;
-
- // Prevent them from been used again if they are wrong.
- // If they are correct, they will the put into CredentialStorage.
+ // Before asking the user for credentials, we check if the URL contains that.
+ if (!username.isEmpty() || !password.isEmpty()) {
+ // Prevent them from been used again if they are wrong.
+ // If they are correct, they will the put into CredentialStorage.
+ if (type == ProtectionSpaceProxyHTTP || type == ProtectionSpaceProxyHTTPS)
+ BlackBerry::Platform::Settings::instance()->setProxyCredential("", "");
+ else {
m_handle->getInternal()->m_user = "";
m_handle->getInternal()->m_pass = "";
- } else {
- if (m_handle->firstRequest().targetType() != ResourceRequest::TargetIsMainFrame && BlackBerry::Platform::Settings::instance()->isChromeProcess())
- return false;
-
- m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge();
- m_frame->page()->chrome()->client()->platformPageClient()->authenticationChallenge(newURL, protectionSpace, Credential(), this);
- return true;
}
+ } else {
+ if (m_handle->firstRequest().targetType() != ResourceRequest::TargetIsMainFrame && BlackBerry::Platform::Settings::instance()->isChromeProcess())
+ return false;
+
+ if (!m_frame || !m_frame->page())
+ return false;
+
+ m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge();
+
+ m_isAuthenticationChallenging = true;
+ updateDeferLoadingCount(1);
+
+ AuthenticationChallengeManager::instance()->authenticationChallenge(newURL, protectionSpace,
+ Credential(), this, m_frame->page()->chrome()->client()->platformPageClient());
+ return false;
}
credential = Credential(username, password, CredentialPersistenceForSession);
@@ -803,10 +843,11 @@ void NetworkJob::storeCredentials()
CredentialStorage::set(challenge.proposedCredential(), challenge.protectionSpace(), m_response.url());
challenge.setStored(true);
- if (challenge.protectionSpace().serverType() == ProtectionSpaceProxyHTTP) {
+ if (challenge.protectionSpace().serverType() == ProtectionSpaceProxyHTTP || challenge.protectionSpace().serverType() == ProtectionSpaceProxyHTTPS) {
BlackBerry::Platform::Settings::instance()->setProxyCredential(challenge.proposedCredential().user().utf8().data(),
challenge.proposedCredential().password().utf8().data());
- m_frame->page()->chrome()->client()->platformPageClient()->syncProxyCredential(challenge.proposedCredential());
+ if (m_frame && m_frame->page())
+ m_frame->page()->chrome()->client()->platformPageClient()->syncProxyCredential(challenge.proposedCredential());
}
}
@@ -836,16 +877,25 @@ void NetworkJob::fireDeleteJobTimer(Timer<NetworkJob>*)
void NetworkJob::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential)
{
- if (result != AuthenticationChallengeSuccess || protectionSpace.host().isEmpty() || !url.isValid()) {
- m_newJobWithCredentialsStarted = false;
- return;
+ ASSERT(url.isValid());
+ ASSERT(url == m_response.url());
+ ASSERT(!protectionSpace.host().isEmpty());
+
+ if (m_isAuthenticationChallenging) {
+ m_isAuthenticationChallenging = false;
+ if (result == AuthenticationChallengeSuccess)
+ cancelJob();
+ updateDeferLoadingCount(-1);
}
+ if (result != AuthenticationChallengeSuccess)
+ return;
+
if (m_handle->getInternal()->m_currentWebChallenge.isNull())
m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError());
ResourceRequest newRequest = m_handle->firstRequest();
- newRequest.setURL(m_response.url());
+ newRequest.setURL(url);
newRequest.setMustHandleInternally(true);
m_newJobWithCredentialsStarted = startNewJobWithRequest(newRequest);
}
diff --git a/Source/WebCore/platform/network/blackberry/NetworkJob.h b/Source/WebCore/platform/network/blackberry/NetworkJob.h
index 3526374ab..4e5749e5d 100644
--- a/Source/WebCore/platform/network/blackberry/NetworkJob.h
+++ b/Source/WebCore/platform/network/blackberry/NetworkJob.h
@@ -29,6 +29,7 @@
#include <network/FilterStream.h>
#include <wtf/OwnPtr.h>
#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace BlackBerry {
@@ -49,6 +50,8 @@ class ResourceRequest;
class NetworkJob : public AuthenticationChallengeClient, public BlackBerry::Platform::FilterStream {
public:
NetworkJob();
+ ~NetworkJob();
+
bool initialize(int playerId,
const String& pageGroupName,
const KURL&,
@@ -66,7 +69,7 @@ public:
int cancelJob();
bool isDeferringLoading() const { return m_deferLoadingCount > 0; }
void updateDeferLoadingCount(int delta);
- virtual void notifyStatusReceived(int status, const char* message);
+ virtual void notifyStatusReceived(int status, const BlackBerry::Platform::String& message);
void handleNotifyStatusReceived(int status, const String& message);
virtual void notifyHeadersReceived(BlackBerry::Platform::NetworkRequest::HeaderList& headers);
virtual void notifyMultipartHeaderReceived(const char* key, const char* value);
@@ -171,6 +174,8 @@ private:
DeferredData m_deferredData;
int m_deferLoadingCount;
const Frame* m_frame;
+
+ bool m_isAuthenticationChallenging;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/network/blackberry/NetworkManager.cpp b/Source/WebCore/platform/network/blackberry/NetworkManager.cpp
index 5d036b501..3d8c54207 100644
--- a/Source/WebCore/platform/network/blackberry/NetworkManager.cpp
+++ b/Source/WebCore/platform/network/blackberry/NetworkManager.cpp
@@ -28,7 +28,6 @@
#include "FrameLoaderClientBlackBerry.h"
#include "NetworkJob.h"
#include "Page.h"
-#include "ReadOnlyLatin1String.h"
#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
#include "ResourceHandleClient.h"
#endif
@@ -87,12 +86,10 @@ bool NetworkManager::startJob(int playerId, const String& pageGroupName, PassRef
const String& documentUrl = frame.document()->url().string();
if (!documentUrl.isEmpty()) {
- ReadOnlyLatin1String referrer(documentUrl);
- platformRequest.setReferrer(referrer.data(), referrer.length());
+ platformRequest.setReferrer(documentUrl);
}
- ReadOnlyLatin1String securityOrigin(frame.document()->securityOrigin()->toRawString());
- platformRequest.setSecurityOrigin(securityOrigin.data(), securityOrigin.length());
+ platformRequest.setSecurityOrigin(frame.document()->securityOrigin()->toRawString());
// Attach any applicable auth credentials to the NetworkRequest.
AuthenticationChallenge& challenge = guardJob->getInternal()->m_currentWebChallenge;
@@ -105,7 +102,7 @@ bool NetworkManager::startJob(int playerId, const String& pageGroupName, PassRef
String password = credential.password();
BlackBerry::Platform::NetworkRequest::AuthType authType = BlackBerry::Platform::NetworkRequest::AuthNone;
- if (type == ProtectionSpaceServerHTTP) {
+ if (type == ProtectionSpaceServerHTTP || type == ProtectionSpaceServerHTTPS) {
switch (protectionSpace.authenticationScheme()) {
case ProtectionSpaceAuthenticationSchemeHTTPBasic:
authType = BlackBerry::Platform::NetworkRequest::AuthHTTPBasic;
@@ -124,9 +121,9 @@ bool NetworkManager::startJob(int playerId, const String& pageGroupName, PassRef
// Defaults to AuthNone as per above.
break;
}
- } else if (type == ProtectionSpaceServerFTP)
+ } else if (type == ProtectionSpaceServerFTP || type == ProtectionSpaceServerFTPS)
authType = BlackBerry::Platform::NetworkRequest::AuthFTP;
- else if (type == ProtectionSpaceProxyHTTP)
+ else if (type == ProtectionSpaceProxyHTTP || type == ProtectionSpaceProxyHTTPS)
authType = BlackBerry::Platform::NetworkRequest::AuthProxy;
if (authType != BlackBerry::Platform::NetworkRequest::AuthNone)
diff --git a/Source/WebCore/platform/network/blackberry/ResourceRequestBlackBerry.cpp b/Source/WebCore/platform/network/blackberry/ResourceRequestBlackBerry.cpp
index eefd5a5e4..bda4021df 100644
--- a/Source/WebCore/platform/network/blackberry/ResourceRequestBlackBerry.cpp
+++ b/Source/WebCore/platform/network/blackberry/ResourceRequestBlackBerry.cpp
@@ -21,7 +21,6 @@
#include "BlobRegistryImpl.h"
#include "CookieManager.h"
-#include "ReadOnlyLatin1String.h"
#include <network/NetworkRequest.h>
#include <wtf/HashMap.h>
#include <wtf/text/CString.h>
@@ -139,7 +138,7 @@ ResourceRequest::TargetType ResourceRequest::targetTypeFromMimeType(const String
if (iter == map.end())
return ResourceRequest::TargetIsUnspecified;
- return iter->second;
+ return iter->value;
}
void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest, bool cookiesEnabled, bool isInitial, bool isRedirect) const
@@ -148,16 +147,14 @@ void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest,
if (isInitial)
platformRequest.setRequestInitial(timeoutInterval());
else {
- ReadOnlyLatin1String latin1URL(url().string());
- ReadOnlyLatin1String latin1HttpMethod(httpMethod());
- platformRequest.setRequestUrl(latin1URL.data(), latin1URL.length(),
- latin1HttpMethod.data(), latin1HttpMethod.length(),
+ platformRequest.setRequestUrl(url().string(),
+ httpMethod(),
platformCachePolicyForRequest(*this),
platformTargetTypeForRequest(*this),
timeoutInterval());
platformRequest.setConditional(isConditional());
- platformRequest.setSuggestedSaveName(suggestedSaveName().utf8().data());
+ platformRequest.setSuggestedSaveName(suggestedSaveName());
if (httpBody() && !httpBody()->isEmpty()) {
const Vector<FormDataElement>& elements = httpBody()->elements();
@@ -197,8 +194,8 @@ void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest,
bool cookieHeaderMayBeDirty = isRedirect || cachePolicy() == WebCore::ReloadIgnoringCacheData || cachePolicy() == WebCore::ReturnCacheDataElseLoad;
for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != httpHeaderFields().end(); ++it) {
- String key = it->first;
- String value = it->second;
+ String key = it->key;
+ String value = it->value;
if (!key.isEmpty()) {
if (equalIgnoringCase(key, "Cookie")) {
// We won't use the old cookies of resourceRequest for new location because these cookies may be changed by redirection.
@@ -210,9 +207,7 @@ void ResourceRequest::initializePlatformRequest(NetworkRequest& platformRequest,
continue;
}
}
- ReadOnlyLatin1String latin1Key(key);
- ReadOnlyLatin1String latin1Value(value);
- platformRequest.addHeader(latin1Key.data(), latin1Key.length(), latin1Value.data(), latin1Value.length());
+ platformRequest.addHeader(key, value);
}
}
diff --git a/Source/WebCore/platform/network/blackberry/SocketStreamHandle.h b/Source/WebCore/platform/network/blackberry/SocketStreamHandle.h
index fce05f1c4..80ec41bd7 100644
--- a/Source/WebCore/platform/network/blackberry/SocketStreamHandle.h
+++ b/Source/WebCore/platform/network/blackberry/SocketStreamHandle.h
@@ -53,7 +53,7 @@ public:
virtual ~SocketStreamHandle();
// FilterStream interface
- virtual void notifyStatusReceived(int status, const char* message);
+ virtual void notifyStatusReceived(int status, const BlackBerry::Platform::String& message);
virtual void notifyDataReceived(BlackBerry::Platform::NetworkBuffer*);
virtual void notifyReadyToSendData();
virtual void notifyClose(int status);
diff --git a/Source/WebCore/platform/network/blackberry/SocketStreamHandleBlackBerry.cpp b/Source/WebCore/platform/network/blackberry/SocketStreamHandleBlackBerry.cpp
index f7d708a68..b7dce3fbd 100644
--- a/Source/WebCore/platform/network/blackberry/SocketStreamHandleBlackBerry.cpp
+++ b/Source/WebCore/platform/network/blackberry/SocketStreamHandleBlackBerry.cpp
@@ -39,7 +39,6 @@
#include "Page.h"
#include "PageClientBlackBerry.h"
#include "PageGroup.h"
-#include "ReadOnlyLatin1String.h"
#include "SocketStreamError.h"
#include "SocketStreamHandleClient.h"
@@ -68,8 +67,7 @@ SocketStreamHandle::SocketStreamHandle(const String& groupName, const KURL& url,
// Open the socket
BlackBerry::Platform::NetworkRequest request;
- ReadOnlyLatin1String latin1URL(url.string());
- request.setRequestUrl(latin1URL.data(), latin1URL.length(), "CONNECT", 7);
+ request.setRequestUrl(url.string(), "CONNECT");
m_socketStream = adoptPtr(factory->createNetworkStream(request, playerId));
ASSERT(m_socketStream);
@@ -99,7 +97,7 @@ void SocketStreamHandle::platformClose()
// FilterStream interface
-void SocketStreamHandle::notifyStatusReceived(int status, const char* message)
+void SocketStreamHandle::notifyStatusReceived(int status, const BlackBerry::Platform::String& message)
{
ASSERT(m_client);
diff --git a/Source/WebCore/platform/network/cf/ResourceError.h b/Source/WebCore/platform/network/cf/ResourceError.h
index 30e0a5ea0..6a8c7daf0 100644
--- a/Source/WebCore/platform/network/cf/ResourceError.h
+++ b/Source/WebCore/platform/network/cf/ResourceError.h
@@ -65,6 +65,7 @@ public:
#if PLATFORM(WIN)
ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription, CFDataRef certificate);
PCCERT_CONTEXT certificate() const;
+ void setCertificate(CFDataRef);
#endif
ResourceError(CFStreamError error);
CFStreamError cfStreamError() const;
diff --git a/Source/WebCore/platform/network/cf/ResourceErrorCF.cpp b/Source/WebCore/platform/network/cf/ResourceErrorCF.cpp
index aa318e665..354fd2758 100644
--- a/Source/WebCore/platform/network/cf/ResourceErrorCF.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceErrorCF.cpp
@@ -62,6 +62,11 @@ PCCERT_CONTEXT ResourceError::certificate() const
return reinterpret_cast<PCCERT_CONTEXT>(CFDataGetBytePtr(m_certificate.get()));
}
+
+void ResourceError::setCertificate(CFDataRef certificate)
+{
+ m_certificate = certificate;
+}
#endif // PLATFORM(WIN)
const CFStringRef failingURLStringKey = CFSTR("NSErrorFailingURLStringKey");
diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index f6d1f3821..01e8b8ae5 100644
--- a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -428,7 +428,7 @@ static CFURLRequestRef makeFinalRequest(const ResourceRequest& request, bool sho
if (!sslProps)
sslProps.adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
#if PLATFORM(WIN)
- wkSetClientCertificateInSSLProperties(sslProps.get(), (clientCert->second).get());
+ wkSetClientCertificateInSSLProperties(sslProps.get(), (clientCert->value).get());
#endif
}
diff --git a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
index 57a6fb2c8..8cff87ca0 100644
--- a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
+++ b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -120,8 +120,8 @@ static inline void setHeaderFields(CFMutableURLRequestRef request, const HTTPHea
HTTPHeaderMap::const_iterator end = requestHeaders.end();
for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
- CFStringRef key = it->first.createCFString();
- CFStringRef value = it->second.createCFString();
+ CFStringRef key = it->key.createCFString();
+ CFStringRef value = it->value.createCFString();
CFURLRequestSetHTTPHeaderFieldValue(request, key, value);
CFRelease(key);
CFRelease(value);
diff --git a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp
index af075ef9e..65bcc10ad 100644
--- a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -703,8 +703,8 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
HTTPHeaderMap customHeaders = job->firstRequest().httpHeaderFields();
HTTPHeaderMap::const_iterator end = customHeaders.end();
for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) {
- String key = it->first;
- String value = it->second;
+ String key = it->key;
+ String value = it->value;
String headerString(key);
headerString.append(": ");
headerString.append(value);
diff --git a/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp b/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp
index 4b1a47f0c..a08489007 100644
--- a/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp
+++ b/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp
@@ -51,6 +51,8 @@ void NetworkStateNotifier::updateState()
// Assume that we're offline until proven otherwise.
m_isOnLine = false;
+ LOG(Network, "Checking online state...");
+
Eina_List* networkInterfaces = eeze_net_list();
Eina_List* list;
@@ -65,17 +67,26 @@ void NetworkStateNotifier::updateState()
// Skip interfaces that are not up.
const char* state = eeze_net_attribute_get(networkInterface, udevOperstateAttribute);
+ LOG(Network, "Found network interface \"%s\" with state: \"%s\"", syspath, state);
if (!state || strcmp(state, udevOperstateUp))
continue;
// Check if the interface has an IP address.
eeze_net_scan(networkInterface);
if (eeze_net_addr_get(networkInterface, EEZE_NET_ADDR_TYPE_IP) || eeze_net_addr_get(networkInterface, EEZE_NET_ADDR_TYPE_IP6)) {
+#if !LOG_DISABLED
+ const char* ipAddress = eeze_net_addr_get(networkInterface, EEZE_NET_ADDR_TYPE_IP);
+ if (!ipAddress)
+ ipAddress = eeze_net_addr_get(networkInterface, EEZE_NET_ADDR_TYPE_IP6);
+ LOG(Network, "Network interface at %s has the following IP address: %s", syspath, ipAddress);
+#endif
m_isOnLine = true;
break;
}
}
+ LOG(Network, "Detected online state is \"%s\"", m_isOnLine ? "online" : "offline");
+
EINA_LIST_FREE(networkInterfaces, data)
eeze_net_free(static_cast<Eeze_Net*>(data));
}
diff --git a/Source/WebCore/platform/network/mac/ResourceErrorMac.mm b/Source/WebCore/platform/network/mac/ResourceErrorMac.mm
index e83990c3d..df6e9868a 100644
--- a/Source/WebCore/platform/network/mac/ResourceErrorMac.mm
+++ b/Source/WebCore/platform/network/mac/ResourceErrorMac.mm
@@ -37,6 +37,22 @@
namespace WebCore {
+static RetainPtr<NSError> createNSErrorFromResourceErrorBase(const ResourceErrorBase& resourceError)
+{
+ RetainPtr<NSMutableDictionary> userInfo(AdoptNS, [[NSMutableDictionary alloc] init]);
+
+ if (!resourceError.localizedDescription().isEmpty())
+ [userInfo.get() setValue:resourceError.localizedDescription() forKey:NSLocalizedDescriptionKey];
+
+ if (!resourceError.failingURL().isEmpty()) {
+ RetainPtr<NSURL> cocoaURL = adoptNS([[NSURL alloc] initWithString:resourceError.failingURL()]);
+ [userInfo.get() setValue:resourceError.failingURL() forKey:@"NSErrorFailingURLStringKey"];
+ [userInfo.get() setValue:cocoaURL.get() forKey:@"NSErrorFailingURLKey"];
+ }
+
+ return RetainPtr<NSError>(AdoptNS, [[NSError alloc] initWithDomain:resourceError.domain() code:resourceError.errorCode() userInfo:userInfo.get()]);
+}
+
#if USE(CFNETWORK)
ResourceError::ResourceError(NSError *error)
@@ -52,11 +68,18 @@ NSError *ResourceError::nsError() const
ASSERT(!m_platformError);
return nil;
}
- if (!m_platformNSError) {
+
+ if (m_platformNSError)
+ return m_platformNSError.get();
+
+ if (m_platformError) {
CFErrorRef error = m_platformError.get();
RetainPtr<NSDictionary> userInfo(AdoptCF, (NSDictionary *) CFErrorCopyUserInfo(error));
m_platformNSError.adoptNS([[NSError alloc] initWithDomain:(NSString *)CFErrorGetDomain(error) code:CFErrorGetCode(error) userInfo:userInfo.get()]);
+ return m_platformNSError.get();
}
+
+ m_platformNSError = createNSErrorFromResourceErrorBase(*this);
return m_platformNSError.get();
}
@@ -72,6 +95,8 @@ ResourceError::ResourceError(NSError *nsError)
, m_platformError(nsError)
{
m_isNull = !nsError;
+ if (!m_isNull)
+ m_isTimeout = [m_platformError.get() code] == NSURLErrorTimedOut;
}
ResourceError::ResourceError(CFErrorRef cfError)
@@ -79,6 +104,8 @@ ResourceError::ResourceError(CFErrorRef cfError)
, m_platformError((NSError *)cfError)
{
m_isNull = !cfError;
+ if (!m_isNull)
+ m_isTimeout = [m_platformError.get() code] == NSURLErrorTimedOut;
}
void ResourceError::platformLazyInit()
@@ -113,21 +140,9 @@ NSError *ResourceError::nsError() const
ASSERT(!m_platformError);
return nil;
}
-
- if (!m_platformError) {
- RetainPtr<NSMutableDictionary> userInfo(AdoptNS, [[NSMutableDictionary alloc] init]);
- if (!m_localizedDescription.isEmpty())
- [userInfo.get() setValue:m_localizedDescription forKey:NSLocalizedDescriptionKey];
-
- if (!m_failingURL.isEmpty()) {
- RetainPtr<NSURL> cocoaURL = adoptNS([[NSURL alloc] initWithString:m_failingURL]);
- [userInfo.get() setValue:m_failingURL forKey:@"NSErrorFailingURLStringKey"];
- [userInfo.get() setValue:cocoaURL.get() forKey:@"NSErrorFailingURLKey"];
- }
-
- m_platformError.adoptNS([[NSError alloc] initWithDomain:m_domain code:m_errorCode userInfo:userInfo.get()]);
- }
+ if (!m_platformError)
+ m_platformError = createNSErrorFromResourceErrorBase(*this);;
return m_platformError.get();
}
diff --git a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
index 96c497d50..93216cb55 100644
--- a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
+++ b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -155,7 +155,7 @@ void ResourceRequest::doUpdatePlatformRequest()
[nsRequest setValue:nil forHTTPHeaderField:[oldHeaderFieldNames objectAtIndex:i - 1]];
HTTPHeaderMap::const_iterator end = httpHeaderFields().end();
for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != end; ++it)
- [nsRequest setValue:it->second forHTTPHeaderField:it->first];
+ [nsRequest setValue:it->value forHTTPHeaderField:it->key];
// The below check can be removed once we require a version of Foundation with -[NSMutableURLRequest setContentDispositionEncodingFallbackArray:] method.
static bool supportsContentDispositionEncodingFallbackArray = [NSMutableURLRequest instancesRespondToSelector:@selector(setContentDispositionEncodingFallbackArray:)];
diff --git a/Source/WebCore/platform/network/qt/DnsPrefetchHelper.h b/Source/WebCore/platform/network/qt/DnsPrefetchHelper.h
index b57729da3..d2ab1cf82 100644
--- a/Source/WebCore/platform/network/qt/DnsPrefetchHelper.h
+++ b/Source/WebCore/platform/network/qt/DnsPrefetchHelper.h
@@ -19,9 +19,9 @@
#ifndef DnsPrefetchHelper_h
#define DnsPrefetchHelper_h
-#include <QObject>
#include <QCache>
#include <QHostInfo>
+#include <QObject>
#include <QSet>
#include <QString>
#include <QTime>
diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 116acb2d4..8abcf8c07 100644
--- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2008, 2012 Digia Plc. and/or its subsidiary(-ies)
Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
Copyright (C) 2008 Holger Hans Peter Freyther
@@ -21,44 +21,38 @@
#include "config.h"
#include "QNetworkReplyHandler.h"
+#include "BlobRegistryImpl.h"
#include "HTTPParsers.h"
#include "MIMETypeRegistry.h"
#include "ResourceHandle.h"
#include "ResourceHandleClient.h"
#include "ResourceHandleInternal.h"
-#include "ResourceResponse.h"
#include "ResourceRequest.h"
+#include "ResourceResponse.h"
#include <QDateTime>
#include <QFile>
#include <QFileInfo>
-#include <QNetworkReply>
#include <QNetworkCookie>
+#include <QNetworkReply>
#include <wtf/text/CString.h>
-#include <QDebug>
#include <QCoreApplication>
-// In Qt 4.8, the attribute for sending a request synchronously will be made public,
-// for now, use this hackish solution for setting the internal attribute.
-const QNetworkRequest::Attribute gSynchronousNetworkRequestAttribute = static_cast<QNetworkRequest::Attribute>(QNetworkRequest::HttpPipeliningWasUsedAttribute + 7);
-
static const int gMaxRedirections = 10;
namespace WebCore {
-// Take a deep copy of the FormDataElement
FormDataIODevice::FormDataIODevice(FormData* data)
- : m_formElements(data ? data->elements() : Vector<FormDataElement>())
- , m_currentFile(0)
+ : m_currentFile(0)
, m_currentDelta(0)
, m_fileSize(0)
, m_dataSize(0)
{
setOpenMode(FormDataIODevice::ReadOnly);
- if (!m_formElements.isEmpty() && m_formElements[0].m_type == FormDataElement::encodedFile)
- openFileForCurrentElement();
+ prepareFormElements(data);
+ prepareCurrentElement();
computeSize();
}
@@ -67,6 +61,71 @@ FormDataIODevice::~FormDataIODevice()
delete m_currentFile;
}
+#if ENABLE(BLOB)
+static void appendBlobResolved(FormData* formData, const KURL& url)
+{
+ RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(KURL(ParsedURLString, url));
+ if (blobData) {
+ BlobDataItemList::const_iterator it = blobData->items().begin();
+ const BlobDataItemList::const_iterator itend = blobData->items().end();
+ for (; it != itend; ++it) {
+ const BlobDataItem& blobItem = *it;
+ if (blobItem.type == BlobDataItem::Data)
+ formData->appendData(blobItem.data->data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
+ else if (blobItem.type == BlobDataItem::File)
+ formData->appendFileRange(blobItem.path, blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
+ else if (blobItem.type == BlobDataItem::Blob)
+ appendBlobResolved(formData, blobItem.url);
+ else
+ ASSERT_NOT_REACHED();
+ }
+ }
+}
+#endif
+
+void FormDataIODevice::prepareFormElements(FormData* formData)
+{
+ if (!formData)
+ return;
+
+#if ENABLE(BLOB)
+ bool hasBlob = false;
+ Vector<FormDataElement>::const_iterator it = formData->elements().begin();
+ const Vector<FormDataElement>::const_iterator itend = formData->elements().end();
+ for (; it != itend; ++it) {
+ if (it->m_type == FormDataElement::encodedBlob) {
+ hasBlob = true;
+ break;
+ }
+ }
+
+ // Resolve all blobs so we only have file and data.
+ if (hasBlob) {
+ RefPtr<FormData> newFormData = FormData::create();
+ newFormData->setAlwaysStream(formData->alwaysStream());
+ newFormData->setIdentifier(formData->identifier());
+ it = formData->elements().begin();
+ for (; it != itend; ++it) {
+ const FormDataElement& element = *it;
+ if (element.m_type == FormDataElement::data)
+ newFormData->appendData(element.m_data.data(), element.m_data.size());
+ else if (element.m_type == FormDataElement::encodedFile)
+ newFormData->appendFileRange(element.m_filename, element.m_fileStart, element.m_fileLength, element.m_expectedFileModificationTime, element.m_shouldGenerateFile);
+ else if (element.m_type == FormDataElement::encodedBlob)
+ appendBlobResolved(newFormData.get(), element.m_url);
+ else
+ ASSERT_NOT_REACHED();
+ }
+ m_formElements = newFormData->elements();
+ return;
+ }
+#endif
+
+ // Take a deep copy of the FormDataElements
+ m_formElements = formData->elements();
+}
+
+
qint64 FormDataIODevice::computeSize()
{
for (int i = 0; i < m_formElements.size(); ++i) {
@@ -75,7 +134,14 @@ qint64 FormDataIODevice::computeSize()
m_dataSize += element.m_data.size();
else {
QFileInfo fi(element.m_filename);
+#if ENABLE(BLOB)
+ qint64 fileEnd = fi.size();
+ if (element.m_fileLength != BlobDataItem::toEndOfFile)
+ fileEnd = qMin<qint64>(fi.size(), element.m_fileStart + element.m_fileLength);
+ m_fileSize += qMax<qint64>(0, fileEnd - element.m_fileStart);
+#else
m_fileSize += fi.size();
+#endif
}
}
return m_dataSize + m_fileSize;
@@ -89,10 +155,24 @@ void FormDataIODevice::moveToNextElement()
m_formElements.remove(0);
- if (m_formElements.isEmpty() || m_formElements[0].m_type == FormDataElement::data)
+ prepareCurrentElement();
+}
+
+void FormDataIODevice::prepareCurrentElement()
+{
+ if (m_formElements.isEmpty())
return;
- openFileForCurrentElement();
+ switch (m_formElements[0].m_type) {
+ case FormDataElement::data:
+ return;
+ case FormDataElement::encodedFile:
+ openFileForCurrentElement();
+ break;
+ default:
+ // At this point encodedBlob should already have been handled.
+ ASSERT_NOT_REACHED();
+ }
}
void FormDataIODevice::openFileForCurrentElement()
@@ -102,6 +182,17 @@ void FormDataIODevice::openFileForCurrentElement()
m_currentFile->setFileName(m_formElements[0].m_filename);
m_currentFile->open(QFile::ReadOnly);
+#if ENABLE(BLOB)
+ if (isValidFileTime(m_formElements[0].m_expectedFileModificationTime)) {
+ QFileInfo info(*m_currentFile);
+ if (!info.exists() || static_cast<time_t>(m_formElements[0].m_expectedFileModificationTime) < info.lastModified().toTime_t()) {
+ moveToNextElement();
+ return;
+ }
+ }
+ if (m_formElements[0].m_fileStart)
+ m_currentFile->seek(m_formElements[0].m_fileStart);
+#endif
}
// m_formElements[0] is the current item. If the destination buffer is
@@ -124,13 +215,23 @@ qint64 FormDataIODevice::readData(char* destination, qint64 size)
if (m_currentDelta == element.m_data.size())
moveToNextElement();
- } else {
- const QByteArray data = m_currentFile->read(available);
+ } else if (element.m_type == FormDataElement::encodedFile) {
+ quint64 toCopy = available;
+#if ENABLE(BLOB)
+ if (element.m_fileLength != BlobDataItem::toEndOfFile)
+ toCopy = qMin<qint64>(toCopy, element.m_fileLength - m_currentDelta);
+#endif
+ const QByteArray data = m_currentFile->read(toCopy);
memcpy(destination+copied, data.constData(), data.size());
+ m_currentDelta += data.size();
copied += data.size();
if (m_currentFile->atEnd() || !m_currentFile->isOpen())
moveToNextElement();
+#if ENABLE(BLOB)
+ else if (element.m_fileLength != BlobDataItem::toEndOfFile && m_currentDelta == element.m_fileLength)
+ moveToNextElement();
+#endif
}
}
@@ -582,6 +683,12 @@ void QNetworkReplyHandler::uploadProgress(qint64 bytesSent, qint64 bytesTotal)
if (!client)
return;
+ if (!bytesTotal) {
+ // When finished QNetworkReply emits a progress of 0 bytes.
+ // Ignore that, to avoid firing twice.
+ return;
+ }
+
client->didSendData(m_resourceHandle, bytesSent, bytesTotal);
}
@@ -606,7 +713,7 @@ FormDataIODevice* QNetworkReplyHandler::getIODevice(const ResourceRequest& reque
QNetworkReply* QNetworkReplyHandler::sendNetworkRequest(QNetworkAccessManager* manager, const ResourceRequest& request)
{
if (m_loadType == SynchronousLoad)
- m_request.setAttribute(gSynchronousNetworkRequestAttribute, true);
+ m_request.setAttribute(QNetworkRequest::SynchronousRequestAttribute, true);
if (!manager)
return 0;
diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
index 4771e88a6..0c46f2f7f 100644
--- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -179,9 +179,11 @@ protected:
qint64 writeData(const char*, qint64);
private:
+ void prepareFormElements(FormData*);
void moveToNextElement();
qint64 computeSize();
void openFileForCurrentElement();
+ void prepareCurrentElement();
private:
Vector<FormDataElement> m_formElements;
diff --git a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
index 262ceb7f6..2c2acbe86 100644
--- a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
+++ b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
@@ -42,10 +42,10 @@
#include <QAbstractNetworkCache>
#include <QCoreApplication>
-#include <QUrl>
#include <QNetworkAccessManager>
-#include <QNetworkRequest>
#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QUrl>
namespace WebCore {
diff --git a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
index dbb7b74dd..e84e677a5 100644
--- a/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
+++ b/Source/WebCore/platform/network/qt/ResourceRequestQt.cpp
@@ -49,8 +49,8 @@ QNetworkRequest ResourceRequest::toNetworkRequest(NetworkingContext *context) co
const HTTPHeaderMap &headers = httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end();
it != end; ++it) {
- QByteArray name = QString(it->first).toLatin1();
- QByteArray value = QString(it->second).toLatin1();
+ QByteArray name = QString(it->key).toLatin1();
+ QByteArray value = QString(it->value).toLatin1();
// QNetworkRequest::setRawHeader() would remove the header if the value is null
// Make sure to set an empty header instead of null header.
if (!value.isNull())
diff --git a/Source/WebCore/platform/network/soup/ResourceError.h b/Source/WebCore/platform/network/soup/ResourceError.h
index 37880e52d..766da0b30 100644
--- a/Source/WebCore/platform/network/soup/ResourceError.h
+++ b/Source/WebCore/platform/network/soup/ResourceError.h
@@ -30,30 +30,30 @@
#include <wtf/gobject/GRefPtr.h>
typedef struct _GTlsCertificate GTlsCertificate;
+typedef struct _SoupRequest SoupRequest;
+typedef struct _SoupMessage SoupMessage;
namespace WebCore {
class ResourceError : public ResourceErrorBase
{
public:
- ResourceError()
- : m_tlsErrors(0)
- {
- }
-
ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription)
: ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
, m_tlsErrors(0)
{
}
- ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription, unsigned tlsErrors, GTlsCertificate* certificate)
- : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription)
- , m_tlsErrors(tlsErrors)
- , m_certificate(certificate)
+ ResourceError()
+ : m_tlsErrors(0)
{
}
+ static ResourceError httpError(SoupMessage*, GError*, SoupRequest*);
+ static ResourceError genericIOError(GError*, SoupRequest*);
+ static ResourceError tlsError(SoupRequest*, unsigned tlsErrors, GTlsCertificate*);
+ static ResourceError timeoutError(const String& failingURL);
+
unsigned tlsErrors() const { return m_tlsErrors; }
GTlsCertificate* certificate() const { return m_certificate.get(); }
diff --git a/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp b/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp
new file mode 100644
index 000000000..a1e0863f8
--- /dev/null
+++ b/Source/WebCore/platform/network/soup/ResourceErrorSoup.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * 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 IGALIA S.L. ``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 "ResourceError.h"
+
+#include "LocalizedStrings.h"
+#define LIBSOUP_USE_UNSTABLE_REQUEST_API
+#include <libsoup/soup-request.h>
+#include <libsoup/soup.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+static String failingURI(SoupRequest* request)
+{
+ ASSERT(request);
+ GOwnPtr<char> uri(soup_uri_to_string(soup_request_get_uri(request), FALSE));
+ return uri.get();
+}
+
+ResourceError ResourceError::httpError(SoupMessage* message, GError* error, SoupRequest* request)
+{
+ if (!message || !SOUP_STATUS_IS_TRANSPORT_ERROR(message->status_code))
+ return genericIOError(error, request);
+ return ResourceError(g_quark_to_string(SOUP_HTTP_ERROR), message->status_code,
+ failingURI(request), String::fromUTF8(message->reason_phrase));
+}
+
+ResourceError ResourceError::genericIOError(GError* error, SoupRequest* request)
+{
+ return ResourceError(g_quark_to_string(G_IO_ERROR), error->code,
+ failingURI(request), String::fromUTF8(error->message));
+}
+
+ResourceError ResourceError::tlsError(SoupRequest* request, unsigned /* tlsErrors */, GTlsCertificate*)
+{
+ return ResourceError(g_quark_to_string(SOUP_HTTP_ERROR), SOUP_STATUS_SSL_FAILED,
+ failingURI(request), unacceptableTLSCertificate());
+}
+
+ResourceError ResourceError::timeoutError(const String& failingURL)
+{
+ // FIXME: This should probably either be integrated into Errors(Gtk/EFL).h or the
+ // networking errors from those files should be moved here.
+
+ // Use the same value as in NSURLError.h
+ static const int timeoutError = -1001;
+ static const char* const errorDomain = "WebKitNetworkError";
+ ResourceError error = ResourceError(errorDomain, timeoutError, failingURL, "Request timed out");
+ error.setIsTimeout(true);
+ return error;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 51c918df2..b1e92f8c4 100644
--- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -7,6 +7,7 @@
* Copyright (C) 2009 Christian Dywan <christian@imendio.com>
* Copyright (C) 2009, 2010, 2011 Igalia S.L.
* Copyright (C) 2009 John Kjellberg <john.kjellberg@power.alstom.com>
+ * Copyright (C) 2012 Intel Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -201,7 +202,7 @@ static void cleanupSoupRequestOperation(ResourceHandle*, bool isDestroying);
static void sendRequestCallback(GObject*, GAsyncResult*, gpointer);
static void readCallback(GObject*, GAsyncResult*, gpointer);
static void closeCallback(GObject*, GAsyncResult*, gpointer);
-static bool startNonHTTPRequest(ResourceHandle*, KURL);
+static gboolean requestTimeoutCallback(void*);
#if ENABLE(WEB_TIMING)
static int milisecondsSinceRequest(double requestTime);
#endif
@@ -230,9 +231,9 @@ static SoupSession* sessionFromContext(NetworkingContext* context)
return (context && context->isValid()) ? context->soupSession() : ResourceHandle::defaultSession();
}
-SoupSession* ResourceHandleInternal::soupSession()
+uint64_t ResourceHandleInternal::initiatingPageID()
{
- return sessionFromContext(m_context.get());
+ return (m_context && m_context->isValid()) ? m_context->initiatingPageID() : 0;
}
ResourceHandle::~ResourceHandle()
@@ -270,6 +271,13 @@ static void ensureSessionIsInitialized(SoupSession* session)
g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
}
+SoupSession* ResourceHandleInternal::soupSession()
+{
+ SoupSession* session = sessionFromContext(m_context.get());
+ ensureSessionIsInitialized(session);
+ return session;
+}
+
static void gotHeadersCallback(SoupMessage* msg, gpointer data)
{
ResourceHandle* handle = static_cast<ResourceHandle*>(data);
@@ -371,6 +379,7 @@ static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroyin
if (d->m_soupMessage) {
g_signal_handlers_disconnect_matched(d->m_soupMessage.get(), G_SIGNAL_MATCH_DATA,
0, 0, 0, 0, handle);
+ g_object_set_data(G_OBJECT(d->m_soupMessage.get()), "handle", 0);
d->m_soupMessage.clear();
}
@@ -379,35 +388,34 @@ static void cleanupSoupRequestOperation(ResourceHandle* handle, bool isDestroyin
d->m_buffer = 0;
}
+ if (d->m_timeoutSource) {
+ g_source_destroy(d->m_timeoutSource.get());
+ d->m_timeoutSource.clear();
+ }
+
if (!isDestroying)
handle->deref();
}
-static ResourceError convertSoupErrorToResourceError(GError* error, SoupRequest* request, SoupMessage* message = 0)
+static bool handleUnignoredTLSErrors(ResourceHandle* handle)
{
- ASSERT(error);
- ASSERT(request);
-
- GOwnPtr<char> uri(soup_uri_to_string(soup_request_get_uri(request), FALSE));
- if (message && SOUP_STATUS_IS_TRANSPORT_ERROR(message->status_code)) {
- return ResourceError(g_quark_to_string(SOUP_HTTP_ERROR),
- static_cast<gint>(message->status_code),
- uri.get(),
- String::fromUTF8(message->reason_phrase));
- }
+ ResourceHandleInternal* d = handle->getInternal();
+ const ResourceResponse& response = d->m_response;
- // Non-transport errors are handled differently.
- return ResourceError(g_quark_to_string(G_IO_ERROR),
- error->code,
- uri.get(),
- String::fromUTF8(error->message));
-}
+ if (!response.soupMessageTLSErrors() || gIgnoreSSLErrors)
+ return false;
-static inline bool hasUnignoredTLSErrors(ResourceHandle* handle)
-{
- return handle->getInternal()->m_response.soupMessageTLSErrors()
- && !gIgnoreSSLErrors
- && !allowsAnyHTTPSCertificateHosts().contains(handle->firstRequest().url().host().lower());
+ String lowercaseHostURL = handle->firstRequest().url().host().lower();
+ if (allowsAnyHTTPSCertificateHosts().contains(lowercaseHostURL))
+ return false;
+
+ // We aren't ignoring errors globally, but the user may have already decided to accept this certificate.
+ CertificatesMap::iterator i = clientCertificates().find(lowercaseHostURL);
+ if (i != clientCertificates().end() && i->value.contains(response.soupMessageCertificate()))
+ return false;
+
+ handle->client()->didFail(handle, ResourceError::tlsError(d->m_soupRequest.get(), response.soupMessageTLSErrors(), response.soupMessageCertificate()));
+ return true;
}
static void sendRequestCallback(GObject*, GAsyncResult* res, gpointer data)
@@ -431,7 +439,7 @@ static void sendRequestCallback(GObject*, GAsyncResult* res, gpointer data)
GOwnPtr<GError> error;
GInputStream* in = soup_request_send_finish(d->m_soupRequest.get(), res, &error.outPtr());
if (error) {
- client->didFail(handle.get(), convertSoupErrorToResourceError(error.get(), d->m_soupRequest.get(), soupMessage));
+ client->didFail(handle.get(), ResourceError::httpError(soupMessage, error.get(), d->m_soupRequest.get()));
cleanupSoupRequestOperation(handle.get());
return;
}
@@ -446,17 +454,11 @@ static void sendRequestCallback(GObject*, GAsyncResult* res, gpointer data)
}
d->m_response.updateFromSoupMessage(soupMessage);
- if (hasUnignoredTLSErrors(handle.get())) {
- CertificatesMap::iterator iter = clientCertificates().find(handle->firstRequest().url().host().lower());
- if (iter == clientCertificates().end() || !iter->second.contains(d->m_response.soupMessageCertificate())) {
- GOwnPtr<char> uri(soup_uri_to_string(soup_request_get_uri(d->m_soupRequest.get()), FALSE));
- client->didFail(handle.get(), ResourceError(g_quark_to_string(SOUP_HTTP_ERROR), SOUP_STATUS_SSL_FAILED,
- uri.get(), unacceptableTLSCertificate(),
- d->m_response.soupMessageTLSErrors(), d->m_response.soupMessageCertificate()));
- cleanupSoupRequestOperation(handle.get());
- return;
- }
+ if (handleUnignoredTLSErrors(handle.get())) {
+ cleanupSoupRequestOperation(handle.get());
+ return;
}
+
} else {
d->m_response.setURL(handle->firstRequest().url());
const gchar* contentType = soup_request_get_content_type(d->m_soupRequest.get());
@@ -670,27 +672,24 @@ static void networkEventCallback(SoupMessage*, GSocketClientEvent event, GIOStre
}
#endif
-static bool startHTTPRequest(ResourceHandle* handle)
-{
- ASSERT(handle);
+static const char* gSoupRequestInitiaingPageIDKey = "wk-soup-request-initiaing-page-id";
- ResourceHandleInternal* d = handle->getInternal();
+static void setSoupRequestInitiaingPageID(SoupRequest* request, uint64_t initiatingPageID)
+{
+ if (!initiatingPageID)
+ return;
- SoupSession* session = d->soupSession();
- ensureSessionIsInitialized(session);
- SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
+ uint64_t* initiatingPageIDPtr = static_cast<uint64_t*>(fastMalloc(sizeof(uint64_t)));
+ *initiatingPageIDPtr = initiatingPageID;
+ g_object_set_data_full(G_OBJECT(request), g_intern_static_string(gSoupRequestInitiaingPageIDKey), initiatingPageIDPtr, fastFree);
+}
- ResourceRequest request(handle->firstRequest());
- KURL url(request.url());
- url.removeFragmentIdentifier();
- request.setURL(url);
+static bool createSoupMessageForHandleAndRequest(ResourceHandle* handle, const ResourceRequest& request)
+{
+ ASSERT(handle);
- GOwnPtr<GError> error;
- d->m_soupRequest = adoptGRef(soup_requester_request(requester, url.string().utf8().data(), &error.outPtr()));
- if (error) {
- d->m_soupRequest = 0;
- return false;
- }
+ ResourceHandleInternal* d = handle->getInternal();
+ ASSERT(d->m_soupRequest);
d->m_soupMessage = adoptGRef(soup_request_http_get_message(SOUP_REQUEST_HTTP(d->m_soupRequest.get())));
if (!d->m_soupMessage)
@@ -702,60 +701,64 @@ static bool startHTTPRequest(ResourceHandle* handle)
if (!handle->shouldContentSniff())
soup_message_disable_feature(soupMessage, SOUP_TYPE_CONTENT_SNIFFER);
- g_signal_connect(soupMessage, "got-headers", G_CALLBACK(gotHeadersCallback), handle);
- g_signal_connect(soupMessage, "restarted", G_CALLBACK(restartedCallback), handle);
- g_signal_connect(soupMessage, "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
-
-#if ENABLE(WEB_TIMING)
- g_signal_connect(soupMessage, "network-event", G_CALLBACK(networkEventCallback), handle);
- g_signal_connect(soupMessage, "wrote-body", G_CALLBACK(wroteBodyCallback), handle);
- g_object_set_data(G_OBJECT(soupMessage), "handle", handle);
-#endif
-
String firstPartyString = request.firstPartyForCookies().string();
if (!firstPartyString.isEmpty()) {
GOwnPtr<SoupURI> firstParty(soup_uri_new(firstPartyString.utf8().data()));
soup_message_set_first_party(soupMessage, firstParty.get());
}
- FormData* httpBody = d->m_firstRequest.httpBody();
- CString contentType = d->m_firstRequest.httpContentType().utf8().data();
- if (httpBody && !httpBody->isEmpty()
- && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {
+ FormData* httpBody = request.httpBody();
+ CString contentType = request.httpContentType().utf8().data();
+ if (httpBody && !httpBody->isEmpty() && !addFormElementsToSoupMessage(soupMessage, contentType.data(), httpBody, d->m_bodySize)) {
// We failed to prepare the body data, so just fail this load.
- g_signal_handlers_disconnect_matched(soupMessage, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, handle);
d->m_soupMessage.clear();
return false;
}
- // balanced by a deref() in cleanupSoupRequestOperation, which should always run
- handle->ref();
-
-#if ENABLE(WEB_TIMING)
- d->m_response.setResourceLoadTiming(ResourceLoadTiming::create());
-#endif
-
// Make sure we have an Accept header for subresources; some sites
// want this to serve some of their subresources
if (!soup_message_headers_get_one(soupMessage->request_headers, "Accept"))
soup_message_headers_append(soupMessage->request_headers, "Accept", "*/*");
- // In the case of XHR .send() and .send("") explicitly tell libsoup
- // to send a zero content-lenght header for consistency
- // with other backends (e.g. Chromium's) and other UA implementations like FF.
- // It's done in the backend here instead of in XHR code since in XHR CORS checking
- // prevents us from this kind of late header manipulation.
+ // In the case of XHR .send() and .send("") explicitly tell libsoup to send a zero content-lenght header
+ // for consistency with other backends (e.g. Chromium's) and other UA implementations like FF. It's done
+ // in the backend here instead of in XHR code since in XHR CORS checking prevents us from this kind of
+ // late header manipulation.
if ((request.httpMethod() == "POST" || request.httpMethod() == "PUT")
&& (!request.httpBody() || request.httpBody()->isEmpty()))
soup_message_headers_set_content_length(soupMessage->request_headers, 0);
- // Send the request only if it's not been explicitly deferred.
- if (!d->m_defersLoading) {
+ g_signal_connect(d->m_soupMessage.get(), "got-headers", G_CALLBACK(gotHeadersCallback), handle);
+ g_signal_connect(d->m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), handle);
+ g_signal_connect(d->m_soupMessage.get(), "wrote-body-data", G_CALLBACK(wroteBodyDataCallback), handle);
+
#if ENABLE(WEB_TIMING)
- d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
+ d->m_response.setResourceLoadTiming(ResourceLoadTiming::create());
+ g_signal_connect(d->m_soupMessage.get(), "network-event", G_CALLBACK(networkEventCallback), handle);
+ g_signal_connect(d->m_soupMessage.get(), "wrote-body", G_CALLBACK(wroteBodyCallback), handle);
+ g_object_set_data(G_OBJECT(d->m_soupMessage.get()), "handle", handle);
#endif
- d->m_cancellable = adoptGRef(g_cancellable_new());
- soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, handle);
+
+ return true;
+}
+
+static bool createSoupRequestAndMessageForHandle(ResourceHandle* handle, bool isHTTPFamilyRequest)
+{
+ ResourceHandleInternal* d = handle->getInternal();
+ SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(d->soupSession(), SOUP_TYPE_REQUESTER));
+
+ GOwnPtr<GError> error;
+ const ResourceRequest& request = handle->firstRequest();
+ d->m_soupRequest = adoptGRef(soup_requester_request(requester, request.urlStringForSoup().utf8().data(), &error.outPtr()));
+ if (error) {
+ d->m_soupRequest.clear();
+ return false;
+ }
+
+ // Non-HTTP family requests do not need a soupMessage, as it's callbacks really only apply to HTTP.
+ if (isHTTPFamilyRequest && !createSoupMessageForHandleAndRequest(handle, request)) {
+ d->m_soupRequest.clear();
+ return false;
}
return true;
@@ -782,27 +785,52 @@ bool ResourceHandle::start(NetworkingContext* context)
d->m_firstRequest.setURL(urlWithCredentials);
}
- KURL url = firstRequest().url();
- String urlString = url.string();
- String protocol = url.protocol();
-
// Used to set the authentication dialog toplevel; may be NULL
d->m_context = context;
- if (equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) {
- if (startHTTPRequest(this))
- return true;
+ // Only allow the POST and GET methods for non-HTTP requests.
+ const ResourceRequest& request = firstRequest();
+ bool isHTTPFamilyRequest = request.url().protocolIsInHTTPFamily();
+ if (!isHTTPFamilyRequest && request.httpMethod() != "GET" && request.httpMethod() != "POST") {
+ this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
+ return true;
}
- if (startNonHTTPRequest(this, url))
+ if (!createSoupRequestAndMessageForHandle(this, isHTTPFamilyRequest)) {
+ this->scheduleFailure(InvalidURLFailure); // Error must not be reported immediately
return true;
+ }
+
+ setSoupRequestInitiaingPageID(d->m_soupRequest.get(), d->initiatingPageID());
- // Error must not be reported immediately
- this->scheduleFailure(InvalidURLFailure);
+ // Send the request only if it's not been explicitly deferred.
+ if (!d->m_defersLoading)
+ sendPendingRequest();
return true;
}
+void ResourceHandle::sendPendingRequest()
+{
+#if ENABLE(WEB_TIMING)
+ if (d->m_response.resourceLoadTiming())
+ d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
+#endif
+
+ if (d->m_firstRequest.timeoutInterval() > 0) {
+ // soup_add_timeout returns a GSource* whose only reference is owned by
+ // the context. We need to have our own reference to it, hence not using adoptRef.
+ d->m_timeoutSource = soup_add_timeout(g_main_context_get_thread_default(),
+ d->m_firstRequest.timeoutInterval() * 1000, requestTimeoutCallback, this);
+ }
+
+ // Balanced by a deref() in cleanupSoupRequestOperation, which should always run.
+ ref();
+
+ d->m_cancellable = adoptGRef(g_cancellable_new());
+ soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, this);
+}
+
void ResourceHandle::cancel()
{
d->m_cancelled = true;
@@ -819,7 +847,7 @@ void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
void ResourceHandle::setClientCertificate(const String& host, GTlsCertificate* certificate)
{
- clientCertificates().add(host.lower(), HostTLSCertificateSet()).iterator->second.add(certificate);
+ clientCertificates().add(host.lower(), HostTLSCertificateSet()).iterator->value.add(certificate);
}
void ResourceHandle::setIgnoreSSLErrors(bool ignoreSSLErrors)
@@ -827,11 +855,12 @@ void ResourceHandle::setIgnoreSSLErrors(bool ignoreSSLErrors)
gIgnoreSSLErrors = ignoreSSLErrors;
}
-static bool hasBeenSent(ResourceHandle* handle)
+static bool waitingToSendRequest(ResourceHandle* handle)
{
- ResourceHandleInternal* d = handle->getInternal();
-
- return d->m_cancellable;
+ // We need to check for d->m_soupRequest because the request may have raised a failure
+ // (for example invalid URLs). We cannot simply check for d->m_scheduledFailure because
+ // it's cleared as soon as the failure event is fired.
+ return handle->getInternal()->m_soupRequest && !handle->getInternal()->m_cancellable;
}
void ResourceHandle::platformSetDefersLoading(bool defersLoading)
@@ -839,21 +868,17 @@ void ResourceHandle::platformSetDefersLoading(bool defersLoading)
if (d->m_cancelled)
return;
- // We only need to take action here to UN-defer loading.
- if (defersLoading)
+ // Except when canceling a possible timeout timer, we only need to take action here to UN-defer loading.
+ if (defersLoading) {
+ if (d->m_timeoutSource) {
+ g_source_destroy(d->m_timeoutSource.get());
+ d->m_timeoutSource.clear();
+ }
return;
+ }
- // We need to check for d->m_soupRequest because the request may
- // have raised a failure (for example invalid URLs). We cannot
- // simply check for d->m_scheduledFailure because it's cleared as
- // soon as the failure event is fired.
- if (!hasBeenSent(this) && d->m_soupRequest) {
-#if ENABLE(WEB_TIMING)
- if (d->m_response.resourceLoadTiming())
- d->m_response.resourceLoadTiming()->requestTime = monotonicallyIncreasingTime();
-#endif
- d->m_cancellable = adoptGRef(g_cancellable_new());
- soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, this);
+ if (waitingToSendRequest(this)) {
+ sendPendingRequest();
return;
}
@@ -939,7 +964,7 @@ static void readCallback(GObject*, GAsyncResult* asyncResult, gpointer data)
GOwnPtr<GError> error;
gssize bytesRead = g_input_stream_read_finish(d->m_inputStream.get(), asyncResult, &error.outPtr());
if (error) {
- client->didFail(handle.get(), convertSoupErrorToResourceError(error.get(), d->m_soupRequest.get()));
+ client->didFail(handle.get(), ResourceError::genericIOError(error.get(), d->m_soupRequest.get()));
cleanupSoupRequestOperation(handle.get());
return;
}
@@ -973,38 +998,13 @@ static void readCallback(GObject*, GAsyncResult* asyncResult, gpointer data)
d->m_cancellable.get(), readCallback, handle.get());
}
-static bool startNonHTTPRequest(ResourceHandle* handle, KURL url)
+static gboolean requestTimeoutCallback(gpointer data)
{
- ASSERT(handle);
-
- if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
- return false;
-
- ResourceHandleInternal* d = handle->getInternal();
-
- SoupSession* session = d->soupSession();
- ensureSessionIsInitialized(session);
- SoupRequester* requester = SOUP_REQUESTER(soup_session_get_feature(session, SOUP_TYPE_REQUESTER));
-
- CString urlStr = url.string().utf8();
-
- GOwnPtr<GError> error;
- d->m_soupRequest = adoptGRef(soup_requester_request(requester, urlStr.data(), &error.outPtr()));
- if (error) {
- d->m_soupRequest = 0;
- return false;
- }
-
- // balanced by a deref() in cleanupSoupRequestOperation, which should always run
- handle->ref();
-
- // Send the request only if it's not been explicitly deferred.
- if (!d->m_defersLoading) {
- d->m_cancellable = adoptGRef(g_cancellable_new());
- soup_request_send_async(d->m_soupRequest.get(), d->m_cancellable.get(), sendRequestCallback, handle);
- }
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(data);
+ handle->client()->didFail(handle.get(), ResourceError::timeoutError(handle->getInternal()->m_firstRequest.url().string()));
+ handle->cancel();
- return true;
+ return FALSE;
}
SoupSession* ResourceHandle::defaultSession()
@@ -1035,4 +1035,10 @@ SoupSession* ResourceHandle::defaultSession()
return session;
}
+uint64_t ResourceHandle::getSoupRequestInitiaingPageID(SoupRequest* request)
+{
+ uint64_t* initiatingPageIDPtr = static_cast<uint64_t*>(g_object_get_data(G_OBJECT(request), gSoupRequestInitiaingPageIDKey));
+ return initiatingPageIDPtr ? *initiatingPageIDPtr : 0;
+}
+
}
diff --git a/Source/WebCore/platform/network/soup/ResourceRequest.h b/Source/WebCore/platform/network/soup/ResourceRequest.h
index 879a47fe8..8ce00fb73 100644
--- a/Source/WebCore/platform/network/soup/ResourceRequest.h
+++ b/Source/WebCore/platform/network/soup/ResourceRequest.h
@@ -74,6 +74,8 @@ namespace WebCore {
SoupMessageFlags soupMessageFlags() const { return m_soupFlags; }
void setSoupMessageFlags(SoupMessageFlags soupFlags) { m_soupFlags = soupFlags; }
+ String urlStringForSoup() const;
+
private:
friend class ResourceRequestBase;
diff --git a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp
index ddfa1c38d..96e23a98a 100644
--- a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp
+++ b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp
@@ -43,7 +43,7 @@ void ResourceRequest::updateSoupMessage(SoupMessage* soupMessage) const
if (!headers.isEmpty()) {
HTTPHeaderMap::const_iterator end = headers.end();
for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
- soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
+ soup_message_headers_append(soupHeaders, it->key.string().utf8().data(), it->value.utf8().data());
}
String firstPartyString = firstPartyForCookies().string();
@@ -66,7 +66,7 @@ SoupMessage* ResourceRequest::toSoupMessage() const
if (!headers.isEmpty()) {
HTTPHeaderMap::const_iterator end = headers.end();
for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
- soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
+ soup_message_headers_append(soupHeaders, it->key.string().utf8().data(), it->value.utf8().data());
}
String firstPartyString = firstPartyForCookies().string();
@@ -124,4 +124,11 @@ unsigned initializeMaximumHTTPConnectionCountPerHost()
return 10000;
}
+String ResourceRequest::urlStringForSoup() const
+{
+ KURL url = m_url;
+ url.removeFragmentIdentifier();
+ return url.string();
+}
+
}
diff --git a/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp b/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp
index b7c048fa1..cdef7ee8f 100644
--- a/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp
+++ b/Source/WebCore/platform/network/soup/ResourceResponseSoup.cpp
@@ -46,7 +46,7 @@ SoupMessage* ResourceResponse::toSoupMessage() const
if (!headers.isEmpty()) {
HTTPHeaderMap::const_iterator end = headers.end();
for (HTTPHeaderMap::const_iterator it = headers.begin(); it != end; ++it)
- soup_message_headers_append(soupHeaders, it->first.string().utf8().data(), it->second.utf8().data());
+ soup_message_headers_append(soupHeaders, it->key.string().utf8().data(), it->value.utf8().data());
}
soup_message_set_flags(soupMessage, m_soupFlags);
diff --git a/Source/WebCore/platform/network/win/ResourceHandleWin.cpp b/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
index 0212d0cda..f25052775 100644
--- a/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
+++ b/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
@@ -323,15 +323,15 @@ bool ResourceHandle::start(NetworkingContext* context)
const HTTPHeaderMap& httpHeaderFields = firstRequest().httpHeaderFields();
for (HTTPHeaderMap::const_iterator it = httpHeaderFields.begin(); it != httpHeaderFields.end(); ++it) {
- if (equalIgnoringCase(it->first, "Accept") || equalIgnoringCase(it->first, "Referer") || equalIgnoringCase(it->first, "User-Agent"))
+ if (equalIgnoringCase(it->key, "Accept") || equalIgnoringCase(it->key, "Referer") || equalIgnoringCase(it->key, "User-Agent"))
continue;
if (!httpHeaders.isEmpty())
httpHeaders.append('\n');
- httpHeaders.append(it->first.characters(), it->first.length());
+ httpHeaders.append(it->key.characters(), it->key.length());
httpHeaders.append(':');
- httpHeaders.append(it->second.characters(), it->second.length());
+ httpHeaders.append(it->value.characters(), it->value.length());
}
INTERNET_BUFFERSW internetBuffers;
diff --git a/Source/WebCore/platform/qt/ClipboardQt.cpp b/Source/WebCore/platform/qt/ClipboardQt.cpp
index e1569926e..6212f58b8 100644
--- a/Source/WebCore/platform/qt/ClipboardQt.cpp
+++ b/Source/WebCore/platform/qt/ClipboardQt.cpp
@@ -48,9 +48,8 @@
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
-#include <QGuiApplication>
#include <QClipboard>
-#include <QImage>
+#include <QGuiApplication>
#include <QList>
#include <QMimeData>
#include <QStringList>
@@ -183,13 +182,13 @@ bool ClipboardQt::setData(const String& type, const String& data)
}
// extensions beyond IE's API
-HashSet<String> ClipboardQt::types() const
+ListHashSet<String> ClipboardQt::types() const
{
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
- return HashSet<String>();
+ return ListHashSet<String>();
ASSERT(m_readableData);
- HashSet<String> result;
+ ListHashSet<String> result;
QStringList formats = m_readableData->formats();
for (int i = 0; i < formats.count(); ++i)
result.add(formats.at(i));
@@ -244,7 +243,7 @@ DragImageRef ClipboardQt::createDragImage(IntPoint& dragLoc) const
if (!m_dragImage)
return 0;
dragLoc = m_dragLoc;
- return new QImage(*m_dragImage->image()->nativeImageForCurrentFrame());
+ return m_dragImage->image()->nativeImageForCurrentFrame();
}
@@ -274,9 +273,9 @@ void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, co
CachedImage* cachedImage = getCachedImage(element);
if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
return;
- QImage* image = cachedImage->imageForRenderer(element->renderer())->nativeImageForCurrentFrame();
- if (image)
- m_writableData->setImageData(*image);
+ QPixmap* pixmap = cachedImage->imageForRenderer(element->renderer())->nativeImageForCurrentFrame();
+ if (pixmap)
+ m_writableData->setImageData(*pixmap);
QList<QUrl> urls;
urls.append(url);
diff --git a/Source/WebCore/platform/qt/ClipboardQt.h b/Source/WebCore/platform/qt/ClipboardQt.h
index 5d09c84f4..b81c148ea 100644
--- a/Source/WebCore/platform/qt/ClipboardQt.h
+++ b/Source/WebCore/platform/qt/ClipboardQt.h
@@ -57,7 +57,7 @@ public:
bool setData(const String& type, const String& data);
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
void setDragImage(CachedImage*, const IntPoint&);
diff --git a/Source/WebCore/platform/qt/CursorQt.cpp b/Source/WebCore/platform/qt/CursorQt.cpp
index 168a2f56b..e7854dde5 100644
--- a/Source/WebCore/platform/qt/CursorQt.cpp
+++ b/Source/WebCore/platform/qt/CursorQt.cpp
@@ -37,8 +37,6 @@
#include "NotImplemented.h"
-#include <QImage>
-#include <QPixmap>
#include <stdio.h>
#include <stdlib.h>
@@ -77,11 +75,10 @@ Cursor& Cursor::operator=(const Cursor& other)
#ifndef QT_NO_CURSOR
static QCursor* createCustomCursor(Image* image, const IntPoint& hotSpot)
{
- QImage* nativeImage = image->nativeImageForCurrentFrame();
- if (!nativeImage)
+ if (!image->nativeImageForCurrentFrame())
return 0;
IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
- return new QCursor(QPixmap::fromImage(*nativeImage), effectiveHotSpot.x(), effectiveHotSpot.y());
+ return new QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y());
}
#endif
diff --git a/Source/WebCore/platform/qt/DragImageQt.cpp b/Source/WebCore/platform/qt/DragImageQt.cpp
index e93ac7089..0e7ce0465 100644
--- a/Source/WebCore/platform/qt/DragImageQt.cpp
+++ b/Source/WebCore/platform/qt/DragImageQt.cpp
@@ -29,8 +29,6 @@
#include "CachedImage.h"
#include "Image.h"
-#include <QImage>
-
namespace WebCore {
IntSize dragImageSize(DragImageRef image)
@@ -68,7 +66,7 @@ DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum)
if (!image || !image->nativeImageForCurrentFrame())
return 0;
- return new QImage(*image->nativeImageForCurrentFrame());
+ return new QPixmap(*image->nativeImageForCurrentFrame());
}
DragImageRef createDragImageIconForCachedImage(CachedImage*)
diff --git a/Source/WebCore/platform/qt/GamepadsQt.cpp b/Source/WebCore/platform/qt/GamepadsQt.cpp
index 624fde947..dc4f16a7a 100644
--- a/Source/WebCore/platform/qt/GamepadsQt.cpp
+++ b/Source/WebCore/platform/qt/GamepadsQt.cpp
@@ -34,7 +34,7 @@
#include <QSocketNotifier>
extern "C" {
- #include <libudev.h>
+#include <libudev.h>
}
#include <unistd.h>
diff --git a/Source/WebCore/platform/qt/PasteboardQt.cpp b/Source/WebCore/platform/qt/PasteboardQt.cpp
index 66b0e4026..96deac499 100644
--- a/Source/WebCore/platform/qt/PasteboardQt.cpp
+++ b/Source/WebCore/platform/qt/PasteboardQt.cpp
@@ -35,9 +35,9 @@
#include "Image.h"
#include "RenderImage.h"
#include "markup.h"
-#include <qguiapplication.h>
#include <qclipboard.h>
#include <qdebug.h>
+#include <qguiapplication.h>
#include <qmimedata.h>
#include <qurl.h>
@@ -168,10 +168,10 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String&)
Image* image = cachedImage->imageForRenderer(node->renderer());
ASSERT(image);
- QImage* nativeImage = image->nativeImageForCurrentFrame();
- if (!image)
+ QPixmap* pixmap = image->nativeImageForCurrentFrame();
+ if (!pixmap)
return;
- QGuiApplication::clipboard()->setImage(*nativeImage, QClipboard::Clipboard);
+ QGuiApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard);
#endif
}
diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
index 62d8a2482..5123a8d8c 100644
--- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
+++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
@@ -42,97 +42,97 @@ String keyIdentifierForQtKeyCode(int keyCode)
switch (keyCode) {
case Qt::Key_Menu:
case Qt::Key_Alt:
- return "Alt";
+ return ASCIILiteral("Alt");
case Qt::Key_Clear:
- return "Clear";
+ return ASCIILiteral("Clear");
case Qt::Key_Down:
- return "Down";
+ return ASCIILiteral("Down");
case Qt::Key_End:
- return "End";
+ return ASCIILiteral("End");
case Qt::Key_Return:
case Qt::Key_Enter:
- return "Enter";
+ return ASCIILiteral("Enter");
case Qt::Key_Execute:
- return "Execute";
+ return ASCIILiteral("Execute");
case Qt::Key_F1:
- return "F1";
+ return ASCIILiteral("F1");
case Qt::Key_F2:
- return "F2";
+ return ASCIILiteral("F2");
case Qt::Key_F3:
- return "F3";
+ return ASCIILiteral("F3");
case Qt::Key_F4:
- return "F4";
+ return ASCIILiteral("F4");
case Qt::Key_F5:
- return "F5";
+ return ASCIILiteral("F5");
case Qt::Key_F6:
- return "F6";
+ return ASCIILiteral("F6");
case Qt::Key_F7:
- return "F7";
+ return ASCIILiteral("F7");
case Qt::Key_F8:
- return "F8";
+ return ASCIILiteral("F8");
case Qt::Key_F9:
- return "F9";
+ return ASCIILiteral("F9");
case Qt::Key_F10:
- return "F10";
+ return ASCIILiteral("F10");
case Qt::Key_F11:
- return "F11";
+ return ASCIILiteral("F11");
case Qt::Key_F12:
- return "F12";
+ return ASCIILiteral("F12");
case Qt::Key_F13:
- return "F13";
+ return ASCIILiteral("F13");
case Qt::Key_F14:
- return "F14";
+ return ASCIILiteral("F14");
case Qt::Key_F15:
- return "F15";
+ return ASCIILiteral("F15");
case Qt::Key_F16:
- return "F16";
+ return ASCIILiteral("F16");
case Qt::Key_F17:
- return "F17";
+ return ASCIILiteral("F17");
case Qt::Key_F18:
- return "F18";
+ return ASCIILiteral("F18");
case Qt::Key_F19:
- return "F19";
+ return ASCIILiteral("F19");
case Qt::Key_F20:
- return "F20";
+ return ASCIILiteral("F20");
case Qt::Key_F21:
- return "F21";
+ return ASCIILiteral("F21");
case Qt::Key_F22:
- return "F22";
+ return ASCIILiteral("F22");
case Qt::Key_F23:
- return "F23";
+ return ASCIILiteral("F23");
case Qt::Key_F24:
- return "F24";
+ return ASCIILiteral("F24");
case Qt::Key_Help:
- return "Help";
+ return ASCIILiteral("Help");
case Qt::Key_Home:
- return "Home";
+ return ASCIILiteral("Home");
case Qt::Key_Insert:
- return "Insert";
+ return ASCIILiteral("Insert");
case Qt::Key_Left:
- return "Left";
+ return ASCIILiteral("Left");
case Qt::Key_PageDown:
- return "PageDown";
+ return ASCIILiteral("PageDown");
case Qt::Key_PageUp:
- return "PageUp";
+ return ASCIILiteral("PageUp");
case Qt::Key_Pause:
- return "Pause";
+ return ASCIILiteral("Pause");
case Qt::Key_Print:
- return "PrintScreen";
+ return ASCIILiteral("PrintScreen");
case Qt::Key_Right:
- return "Right";
+ return ASCIILiteral("Right");
case Qt::Key_Select:
- return "Select";
+ return ASCIILiteral("Select");
case Qt::Key_Up:
- return "Up";
+ return ASCIILiteral("Up");
// Standard says that DEL becomes U+007F.
case Qt::Key_Delete:
- return "U+007F";
+ return ASCIILiteral("U+007F");
case Qt::Key_Backspace:
- return "U+0008";
+ return ASCIILiteral("U+0008");
case Qt::Key_Tab:
- return "U+0009";
+ return ASCIILiteral("U+0009");
case Qt::Key_Backtab:
- return "U+0009";
+ return ASCIILiteral("U+0009");
default:
return String::format("U+%04X", toupper(keyCode));
}
@@ -585,11 +585,11 @@ static String keyTextForKeyEvent(const QKeyEvent* event)
case Qt::Key_Tab:
case Qt::Key_Backtab:
if (event->text().isNull())
- return "\t";
+ return ASCIILiteral("\t");
break;
case Qt::Key_Enter:
if (event->text().isNull())
- return "\r";
+ return ASCIILiteral("\r");
}
return event->text();
}
diff --git a/Source/WebCore/platform/qt/PlatformScreenQt.cpp b/Source/WebCore/platform/qt/PlatformScreenQt.cpp
index fa2e837ea..d08230299 100644
--- a/Source/WebCore/platform/qt/PlatformScreenQt.cpp
+++ b/Source/WebCore/platform/qt/PlatformScreenQt.cpp
@@ -36,8 +36,8 @@
#include "FrameView.h"
#include "HostWindow.h"
#include "NotImplemented.h"
-#include "Widget.h"
#include "QWebPageClient.h"
+#include "Widget.h"
#include <QGuiApplication>
#include <QScreen>
diff --git a/Source/WebCore/platform/qt/QStyleFacade.cpp b/Source/WebCore/platform/qt/QStyleFacade.cpp
new file mode 100644
index 000000000..4707a2fc1
--- /dev/null
+++ b/Source/WebCore/platform/qt/QStyleFacade.cpp
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the theme implementation for form controls in WebCore.
+ *
+ * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ * Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "QStyleFacade.h"
+
+#include "QWebPageClient.h"
+#include <Chrome.h>
+#include <ChromeClient.h>
+#include <Page.h>
+
+namespace WebCore {
+
+QStyle* QStyleFacade::styleForPage(Page* page)
+{
+ if (!page)
+ return 0;
+ QWebPageClient* pageClient = page->chrome()->client()->platformPageClient();
+
+ if (!pageClient)
+ return 0;
+
+ return pageClient->style();
+}
+
+}
diff --git a/Source/WebCore/platform/qt/QStyleFacade.h b/Source/WebCore/platform/qt/QStyleFacade.h
new file mode 100644
index 000000000..73e8362b1
--- /dev/null
+++ b/Source/WebCore/platform/qt/QStyleFacade.h
@@ -0,0 +1,201 @@
+/*
+ * This file is part of the theme implementation for form controls in WebCore.
+ *
+ * Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+ * Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef QStyleFacade_h
+#define QStyleFacade_h
+
+#include <QPalette>
+#include <QRect>
+
+QT_BEGIN_NAMESPACE
+class QStyle;
+QT_END_NAMESPACE
+
+namespace WebCore {
+
+class Page;
+class QStyleFacadeOption;
+
+class QStyleFacade {
+public:
+ enum ButtonSubElement {
+ PushButtonLayoutItem,
+ PushButtonContents
+ };
+
+#define FOR_EACH_MAPPED_STATE(F, SEPARATOR) \
+ F(State_None, 0x00000000) SEPARATOR \
+ F(State_Enabled, 0x00000001) SEPARATOR \
+ F(State_Raised, 0x00000002) SEPARATOR \
+ F(State_Sunken, 0x00000004) SEPARATOR \
+ F(State_Off, 0x00000008) SEPARATOR \
+ F(State_NoChange, 0x00000010) SEPARATOR \
+ F(State_On, 0x00000020) SEPARATOR \
+ F(State_DownArrow, 0x00000040) SEPARATOR \
+ F(State_Horizontal, 0x00000080) SEPARATOR \
+ F(State_HasFocus, 0x00000100) SEPARATOR \
+ F(State_Top, 0x00000200) SEPARATOR \
+ F(State_Bottom, 0x00000400) SEPARATOR \
+ F(State_FocusAtBorder, 0x00000800) SEPARATOR \
+ F(State_AutoRaise, 0x00001000) SEPARATOR \
+ F(State_MouseOver, 0x00002000) SEPARATOR \
+ F(State_UpArrow, 0x00004000) SEPARATOR \
+ F(State_Selected, 0x00008000) SEPARATOR \
+ F(State_Active, 0x00010000) SEPARATOR \
+ F(State_Window, 0x00020000) SEPARATOR \
+ F(State_Open, 0x00040000) SEPARATOR \
+ F(State_Children, 0x00080000) SEPARATOR \
+ F(State_Item, 0x00100000) SEPARATOR \
+ F(State_Sibling, 0x00200000) SEPARATOR \
+ F(State_Editing, 0x00400000) SEPARATOR \
+ F(State_KeyboardFocusChange, 0x00800000) SEPARATOR \
+ F(State_ReadOnly, 0x02000000) SEPARATOR \
+ F(State_Small, 0x04000000) SEPARATOR \
+ F(State_Mini, 0x0800000)
+
+#define COMMA ,
+#define SEMICOLON ;
+#define DEFINE_MAPPED_STATE(Name, Value) \
+ Name = Value
+
+ // ### Remove unused states.
+ enum StateFlag {
+ FOR_EACH_MAPPED_STATE(DEFINE_MAPPED_STATE, COMMA)
+ };
+ Q_DECLARE_FLAGS(State, StateFlag)
+
+#define FOR_EACH_MAPPED_METRIC(F, SEPARATOR) \
+ F(PM_ButtonMargin) SEPARATOR \
+ F(PM_DefaultFrameWidth) SEPARATOR \
+ F(PM_IndicatorWidth) SEPARATOR \
+ F(PM_ExclusiveIndicatorWidth) SEPARATOR \
+ F(PM_ButtonIconSize)
+
+#define DEFINE_METRIC(F) F
+
+ enum PixelMetric {
+ FOR_EACH_MAPPED_METRIC(DEFINE_METRIC, COMMA)
+ };
+
+#define FOR_EACH_SUBCONTROL(F, SEPARATOR) \
+ F(SC_None, 0x00000000) SEPARATOR \
+ F(SC_ScrollBarAddLine, 0x00000001) SEPARATOR \
+ F(SC_ScrollBarSubLine, 0x00000002) SEPARATOR \
+ F(SC_ScrollBarAddPage, 0x00000004) SEPARATOR \
+ F(SC_ScrollBarSubPage, 0x00000008) SEPARATOR \
+ F(SC_ScrollBarFirst, 0x00000010) SEPARATOR \
+ F(SC_ScrollBarLast, 0x00000020) SEPARATOR \
+ F(SC_ScrollBarSlider, 0x00000040) SEPARATOR \
+ F(SC_ScrollBarGroove, 0x00000080)
+
+#define DEFINE_SUBCONTROL(F, Value) F
+
+ enum SubControl {
+ FOR_EACH_SUBCONTROL(DEFINE_SUBCONTROL, COMMA)
+ };
+
+ virtual ~QStyleFacade() { }
+
+ virtual QRect buttonSubElementRect(ButtonSubElement buttonElement, State, const QRect& originalRect) const = 0;
+
+ virtual int findFrameLineWidth() const = 0;
+ virtual int simplePixelMetric(PixelMetric, State = State_None) const = 0;
+ virtual int buttonMargin(State, const QRect& originalRect) const = 0;
+ virtual int sliderLength(Qt::Orientation) const = 0;
+ virtual int sliderThickness(Qt::Orientation) const = 0;
+ virtual int progressBarChunkWidth(const QSize&) const = 0;
+ virtual void getButtonMetrics(QString* buttonFontFamily, int* buttonFontPixelSize) const = 0;
+
+ virtual QSize comboBoxSizeFromContents(State, const QSize& contentsSize) const = 0;
+ virtual QSize pushButtonSizeFromContents(State, const QSize& contentsSize) const = 0;
+
+ enum ButtonType {
+ PushButton,
+ RadioButton,
+ CheckBox
+ };
+
+ virtual void paintButton(QPainter*, ButtonType, const QStyleFacadeOption&) = 0;
+ virtual void paintTextField(QPainter*, const QStyleFacadeOption&) = 0;
+ virtual void paintComboBox(QPainter*, const QStyleFacadeOption&) = 0;
+ virtual void paintComboBoxArrow(QPainter*, const QStyleFacadeOption&) = 0;
+
+ virtual void paintSliderTrack(QPainter*, const QStyleFacadeOption&) = 0;
+ virtual void paintSliderThumb(QPainter*, const QStyleFacadeOption&) = 0;
+ virtual void paintInnerSpinButton(QPainter*, const QStyleFacadeOption&, bool spinBoxUp) = 0;
+ virtual void paintProgressBar(QPainter*, const QStyleFacadeOption&, double progress, double animationProgress) = 0;
+
+ virtual int scrollBarExtent(bool mini) = 0;
+ virtual bool scrollBarMiddleClickAbsolutePositionStyleHint() const = 0;
+ virtual void paintScrollCorner(QPainter*, const QRect&) = 0;
+
+ virtual SubControl hitTestScrollBar(const QStyleFacadeOption&, const QPoint& pos) = 0;
+ virtual QRect scrollBarSubControlRect(const QStyleFacadeOption&, SubControl) = 0;
+ virtual void paintScrollBar(QPainter*, const QStyleFacadeOption&) = 0;
+
+ virtual QObject* widgetForPainter(QPainter*) = 0;
+
+ virtual bool isValid() const = 0;
+
+ static QStyle* styleForPage(Page*);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleFacade::State)
+
+struct QStyleFacadeOption {
+ QStyleFacadeOption()
+ : state(QStyleFacade::State_None)
+ , direction(Qt::LayoutDirectionAuto)
+ {
+ slider.orientation = Qt::Horizontal;
+ slider.upsideDown = false;
+ slider.minimum = 0;
+ slider.maximum = 0;
+ slider.position = 0;
+ slider.value = 0;
+ slider.singleStep = 0;
+ slider.pageStep = 0;
+ slider.activeSubControls = QStyleFacade::SC_None;
+ }
+
+ QStyleFacade::State state;
+ QRect rect;
+ Qt::LayoutDirection direction;
+ QPalette palette;
+
+ // Slider features
+ struct {
+ Qt::Orientation orientation;
+ bool upsideDown;
+ int minimum;
+ int maximum;
+ int position;
+ int value;
+ int singleStep;
+ int pageStep;
+ QStyleFacade::SubControl activeSubControls;
+ } slider;
+};
+
+}
+
+#endif // QStyleFacade_h
diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.cpp b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp
new file mode 100644
index 000000000..f7e8bf5c9
--- /dev/null
+++ b/Source/WebCore/platform/qt/RenderThemeQStyle.cpp
@@ -0,0 +1,620 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2008-2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * 2006 Dirk Mueller <mueller@kde.org>
+ * 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ *
+ * 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderThemeQStyle.h"
+
+#include "CSSFontSelector.h"
+#include "CSSValueKeywords.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Color.h"
+#include "Document.h"
+#include "Font.h"
+#include "FontSelector.h"
+#include "GraphicsContext.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PaintInfo.h"
+#include "QWebPageClient.h"
+#include "RenderBox.h"
+#if ENABLE(PROGRESS_ELEMENT)
+#include "RenderProgress.h"
+#endif
+#include "RenderSlider.h"
+#include "ScrollbarThemeQStyle.h"
+#include "SliderThumbElement.h"
+#include "StyleResolver.h"
+#include "UserAgentStyleSheets.h"
+
+#include <QPainter>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+QSharedPointer<StylePainter> RenderThemeQStyle::getStylePainter(const PaintInfo& paintInfo)
+{
+ return QSharedPointer<StylePainter>(new StylePainterQStyle(this, paintInfo, /*RenderObject*/0));
+}
+
+StylePainterQStyle::StylePainterQStyle(RenderThemeQStyle* theme, const PaintInfo& paintInfo, RenderObject* renderObject)
+ : StylePainter(theme, paintInfo)
+ , qStyle(theme->qStyle())
+ , appearance(NoControlPart)
+{
+ init(paintInfo.context ? paintInfo.context : 0);
+ if (renderObject)
+ appearance = theme->initializeCommonQStyleOptions(styleOption, renderObject);
+}
+
+StylePainterQStyle::StylePainterQStyle(ScrollbarThemeQStyle* theme, GraphicsContext* context)
+ : StylePainter()
+ , qStyle(theme->qStyle())
+ , appearance(NoControlPart)
+{
+ init(context);
+}
+
+void StylePainterQStyle::init(GraphicsContext* context)
+{
+ painter = static_cast<QPainter*>(context->platformContext());
+ if (QObject* widget = qStyle->widgetForPainter(painter)) {
+ styleOption.palette = widget->property("palette").value<QPalette>();
+ styleOption.rect = widget->property("rect").value<QRect>();
+ styleOption.direction = static_cast<Qt::LayoutDirection>(widget->property("layoutDirection").toInt());
+ }
+
+ StylePainter::init(context);
+}
+
+PassRefPtr<RenderTheme> RenderThemeQStyle::create(Page* page)
+{
+ return adoptRef(new RenderThemeQStyle(page));
+}
+
+static QtStyleFactoryFunction styleFactoryFunction;
+
+void RenderThemeQStyle::setStyleFactoryFunction(QtStyleFactoryFunction function)
+{
+ styleFactoryFunction = function;
+}
+
+QtStyleFactoryFunction RenderThemeQStyle::styleFactory()
+{
+ return styleFactoryFunction;
+}
+
+RenderThemeQStyle::RenderThemeQStyle(Page* page)
+ : RenderThemeQt(page)
+ , m_qStyle(adoptPtr(styleFactoryFunction(page)))
+{
+ int buttonPixelSize = 0;
+ m_qStyle->getButtonMetrics(&m_buttonFontFamily, &buttonPixelSize);
+#ifdef Q_WS_MAC
+ m_buttonFontPixelSize = buttonPixelSize;
+#endif
+}
+
+RenderThemeQStyle::~RenderThemeQStyle()
+{
+}
+
+void RenderThemeQStyle::setPaletteFromPageClientIfExists(QPalette& palette) const
+{
+ if (!m_page)
+ return;
+
+ ASSERT(m_page->chrome());
+ ChromeClient* chromeClient = m_page->chrome()->client();
+ if (!chromeClient)
+ return;
+
+ if (QWebPageClient* pageClient = chromeClient->platformPageClient())
+ palette = pageClient->palette();
+}
+
+QRect RenderThemeQStyle::inflateButtonRect(const QRect& originalRect) const
+{
+ QRect layoutRect = m_qStyle->buttonSubElementRect(QStyleFacade::PushButtonLayoutItem, QStyleFacade::State_Small, originalRect);
+ if (!layoutRect.isNull()) {
+ int paddingLeft = layoutRect.left() - originalRect.left();
+ int paddingRight = originalRect.right() - layoutRect.right();
+ int paddingTop = layoutRect.top() - originalRect.top();
+ int paddingBottom = originalRect.bottom() - layoutRect.bottom();
+
+ return originalRect.adjusted(-paddingLeft, -paddingTop, paddingRight, paddingBottom);
+ }
+ return originalRect;
+}
+
+void RenderThemeQStyle::computeSizeBasedOnStyle(RenderStyle* renderStyle) const
+{
+ QSize size(0, 0);
+ const QFontMetrics fm(renderStyle->font().syntheticFont());
+
+ switch (renderStyle->appearance()) {
+ case TextAreaPart:
+ case SearchFieldPart:
+ case TextFieldPart: {
+ int padding = m_qStyle->findFrameLineWidth();
+ renderStyle->setPaddingLeft(Length(padding, Fixed));
+ renderStyle->setPaddingRight(Length(padding, Fixed));
+ renderStyle->setPaddingTop(Length(padding, Fixed));
+ renderStyle->setPaddingBottom(Length(padding, Fixed));
+ break;
+ }
+ default:
+ break;
+ }
+ // If the width and height are both specified, then we have nothing to do.
+ if (!renderStyle->width().isIntrinsicOrAuto() && !renderStyle->height().isAuto())
+ return;
+
+ switch (renderStyle->appearance()) {
+ case CheckboxPart: {
+ int checkBoxWidth = m_qStyle->simplePixelMetric(QStyleFacade::PM_IndicatorWidth, QStyleFacade::State_Small);
+ checkBoxWidth *= renderStyle->effectiveZoom();
+ size = QSize(checkBoxWidth, checkBoxWidth);
+ break;
+ }
+ case RadioPart: {
+ int radioWidth = m_qStyle->simplePixelMetric(QStyleFacade::PM_ExclusiveIndicatorWidth, QStyleFacade::State_Small);
+ radioWidth *= renderStyle->effectiveZoom();
+ size = QSize(radioWidth, radioWidth);
+ break;
+ }
+ case PushButtonPart:
+ case ButtonPart: {
+ QSize contentSize = fm.size(Qt::TextShowMnemonic, QString::fromLatin1("X"));
+ QSize pushButtonSize = m_qStyle->pushButtonSizeFromContents(QStyleFacade::State_Small, contentSize);
+ QRect layoutRect = m_qStyle->buttonSubElementRect(QStyleFacade::PushButtonLayoutItem, QStyleFacade::State_Small, QRect(0, 0, pushButtonSize.width(), pushButtonSize.height()));
+
+ // If the style supports layout rects we use that, and compensate accordingly
+ // in paintButton() below.
+ if (!layoutRect.isNull())
+ size.setHeight(layoutRect.height());
+ else
+ size.setHeight(pushButtonSize.height());
+
+ break;
+ }
+ case MenulistPart: {
+ int contentHeight = qMax(fm.lineSpacing(), 14) + 2;
+ QSize menuListSize = m_qStyle->comboBoxSizeFromContents(QStyleFacade::State_Small, QSize(0, contentHeight));
+ size.setHeight(menuListSize.height());
+ break;
+ }
+ default:
+ break;
+ }
+
+ // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
+ if (renderStyle->width().isIntrinsicOrAuto() && size.width() > 0)
+ renderStyle->setMinWidth(Length(size.width(), Fixed));
+ if (renderStyle->height().isAuto() && size.height() > 0)
+ renderStyle->setMinHeight(Length(size.height(), Fixed));
+}
+
+
+
+void RenderThemeQStyle::adjustButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element*) const
+{
+ // Ditch the border.
+ style->resetBorder();
+
+#ifdef Q_WS_MAC
+ if (style->appearance() == PushButtonPart) {
+ // The Mac ports ignore the specified height for <input type="button"> elements
+ // unless a border and/or background CSS property is also specified.
+ style->setHeight(Length(Auto));
+ }
+#endif
+
+ FontDescription fontDescription = style->fontDescription();
+ fontDescription.setIsAbsoluteSize(true);
+
+#ifdef Q_WS_MAC // Use fixed font size and family on Mac (like Safari does)
+ fontDescription.setSpecifiedSize(m_buttonFontPixelSize);
+ fontDescription.setComputedSize(m_buttonFontPixelSize);
+#else
+ fontDescription.setSpecifiedSize(style->fontSize());
+ fontDescription.setComputedSize(style->fontSize());
+#endif
+
+ FontFamily fontFamily;
+ fontFamily.setFamily(m_buttonFontFamily);
+ fontDescription.setFamily(fontFamily);
+ style->setFontDescription(fontDescription);
+ style->font().update(styleResolver->fontSelector());
+ style->setLineHeight(RenderStyle::initialLineHeight());
+ setButtonSize(style);
+ setButtonPadding(style);
+}
+
+void RenderThemeQStyle::setButtonPadding(RenderStyle* style) const
+{
+ // Fake a button rect here, since we're just computing deltas
+ QRect originalRect = QRect(0, 0, 100, 30);
+
+ // Default padding is based on the button margin pixel metric
+ int buttonMargin = m_qStyle->buttonMargin(QStyleFacade::State_Small, originalRect);
+ int paddingLeft = buttonMargin;
+ int paddingRight = buttonMargin;
+ int paddingTop = buttonMargin;
+ int paddingBottom = buttonMargin;
+
+ // Then check if the style uses layout margins
+ QRect layoutRect = m_qStyle->buttonSubElementRect(QStyleFacade::PushButtonLayoutItem, QStyleFacade::State_Small, originalRect);
+ if (!layoutRect.isNull()) {
+ QRect contentsRect = m_qStyle->buttonSubElementRect(QStyleFacade::PushButtonContents, QStyleFacade::State_Small, originalRect);
+ paddingLeft = contentsRect.left() - layoutRect.left();
+ paddingRight = layoutRect.right() - contentsRect.right();
+ paddingTop = contentsRect.top() - layoutRect.top();
+
+ // Can't use this right now because we don't have the baseline to compensate
+ // paddingBottom = layoutRect.bottom() - contentsRect.bottom();
+ }
+ style->setPaddingLeft(Length(paddingLeft, Fixed));
+ style->setPaddingRight(Length(paddingRight, Fixed));
+ style->setPaddingTop(Length(paddingTop, Fixed));
+ style->setPaddingBottom(Length(paddingBottom, Fixed));
+}
+
+bool RenderThemeQStyle::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ StylePainterQStyle p(this, i, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = r;
+ p.styleOption.state |= QStyleFacade::State_Small;
+
+ if (p.appearance == PushButtonPart || p.appearance == ButtonPart) {
+ p.styleOption.rect = inflateButtonRect(p.styleOption.rect);
+ p.paintButton(QStyleFacade::PushButton);
+ } else if (p.appearance == RadioPart)
+ p.paintButton(QStyleFacade::RadioButton);
+ else if (p.appearance == CheckboxPart)
+ p.paintButton(QStyleFacade::CheckBox);
+
+ return false;
+}
+
+bool RenderThemeQStyle::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ StylePainterQStyle p(this, i, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = r;
+ p.styleOption.state |= QStyleFacade::State_Sunken;
+
+ // Get the correct theme data for a text field
+ if (p.appearance != TextFieldPart
+ && p.appearance != SearchFieldPart
+ && p.appearance != TextAreaPart
+ && p.appearance != ListboxPart)
+ return true;
+
+ // Now paint the text field.
+ p.paintTextField();
+ return false;
+}
+
+void RenderThemeQStyle::adjustTextAreaStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
+{
+ adjustTextFieldStyle(styleResolver, style, element);
+}
+
+bool RenderThemeQStyle::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ return paintTextField(o, i, r);
+}
+
+void RenderThemeQStyle::setPopupPadding(RenderStyle* style) const
+{
+ const int paddingLeft = 4;
+ const int paddingRight = style->width().isFixed() || style->width().isPercent() ? 5 : 8;
+
+ style->setPaddingLeft(Length(paddingLeft, Fixed));
+
+ int w = m_qStyle->simplePixelMetric(QStyleFacade::PM_ButtonIconSize);
+ style->setPaddingRight(Length(paddingRight + w, Fixed));
+
+ style->setPaddingTop(Length(2, Fixed));
+ style->setPaddingBottom(Length(2, Fixed));
+}
+
+QPalette RenderThemeQStyle::colorPalette() const
+{
+ QPalette palette = RenderThemeQt::colorPalette();
+ setPaletteFromPageClientIfExists(palette);
+ return palette;
+}
+
+bool RenderThemeQStyle::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ StylePainterQStyle p(this, i, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = r;
+ p.paintComboBox();
+ return false;
+}
+
+void RenderThemeQStyle::adjustMenuListButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
+{
+ // WORKAROUND because html.css specifies -webkit-border-radius for <select> so we override it here
+ // see also http://bugs.webkit.org/show_bug.cgi?id=18399
+ style->resetBorderRadius();
+
+ RenderThemeQt::adjustMenuListButtonStyle(styleResolver, style, e);
+}
+
+bool RenderThemeQStyle::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ StylePainterQStyle p(this, i, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = r;
+ p.paintComboBoxArrow();
+ return false;
+}
+
+#if ENABLE(PROGRESS_ELEMENT)
+double RenderThemeQStyle::animationDurationForProgressBar(RenderProgress* renderProgress) const
+{
+ if (renderProgress->position() >= 0)
+ return 0;
+
+ IntSize size = renderProgress->pixelSnappedSize();
+ // FIXME: Until http://bugreports.qt.nokia.com/browse/QTBUG-9171 is fixed,
+ // we simulate one square animating across the progress bar.
+ return (size.width() / m_qStyle->progressBarChunkWidth(size)) * animationRepeatIntervalForProgressBar(renderProgress);
+}
+
+bool RenderThemeQStyle::paintProgressBar(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ if (!o->isProgress())
+ return true;
+
+ StylePainterQStyle p(this, pi, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = r;
+ RenderProgress* renderProgress = toRenderProgress(o);
+ p.paintProgressBar(renderProgress->position(), renderProgress->animationProgress());
+ return false;
+}
+#endif
+
+bool RenderThemeQStyle::paintSliderTrack(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ StylePainterQStyle p(this, pi, o);
+ if (!p.isValid())
+ return true;
+
+ const QPoint topLeft = r.location();
+ p.painter->translate(topLeft);
+
+ p.styleOption.rect = r;
+ p.styleOption.rect.moveTo(QPoint(0, 0));
+
+ if (p.appearance == SliderVerticalPart)
+ p.styleOption.slider.orientation = Qt::Vertical;
+
+ if (isPressed(o))
+ p.styleOption.state |= QStyleFacade::State_Sunken;
+
+ // some styles need this to show a highlight on one side of the groove
+ HTMLInputElement* slider = o->node()->toInputElement();
+ if (slider) {
+ p.styleOption.slider.upsideDown = (p.appearance == SliderHorizontalPart) && !o->style()->isLeftToRightDirection();
+ // Use the width as a multiplier in case the slider values are <= 1
+ const int width = r.width() > 0 ? r.width() : 100;
+ p.styleOption.slider.maximum = slider->maximum() * width;
+ p.styleOption.slider.minimum = slider->minimum() * width;
+ if (!p.styleOption.slider.upsideDown)
+ p.styleOption.slider.position = slider->valueAsNumber() * width;
+ else
+ p.styleOption.slider.position = p.styleOption.slider.minimum + p.styleOption.slider.maximum - slider->valueAsNumber() * width;
+ }
+
+ p.paintSliderTrack();
+
+ p.painter->translate(-topLeft);
+ return false;
+}
+
+void RenderThemeQStyle::adjustSliderTrackStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+ style->setBoxShadow(nullptr);
+}
+
+bool RenderThemeQStyle::paintSliderThumb(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ StylePainterQStyle p(this, pi, o);
+ if (!p.isValid())
+ return true;
+
+ const QPoint topLeft = r.location();
+ p.painter->translate(topLeft);
+
+ p.styleOption.rect = r;
+ p.styleOption.rect.moveTo(QPoint(0, 0));
+ p.styleOption.slider.orientation = Qt::Horizontal;
+ if (p.appearance == SliderThumbVerticalPart)
+ p.styleOption.slider.orientation = Qt::Vertical;
+ if (isPressed(o))
+ p.styleOption.state |= QStyleFacade::State_Sunken;
+
+ p.paintSliderThumb();
+
+ p.painter->translate(-topLeft);
+ return false;
+}
+
+void RenderThemeQStyle::adjustSliderThumbStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
+{
+ RenderTheme::adjustSliderThumbStyle(styleResolver, style, element);
+ style->setBoxShadow(nullptr);
+}
+
+bool RenderThemeQStyle::paintSearchField(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ return paintTextField(o, pi, r);
+}
+
+void RenderThemeQStyle::adjustSearchFieldDecorationStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldDecorationStyle(styleResolver, style, e);
+}
+
+bool RenderThemeQStyle::paintSearchFieldDecoration(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSearchFieldDecoration(o, pi, r);
+}
+
+void RenderThemeQStyle::adjustSearchFieldResultsDecorationStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
+{
+ notImplemented();
+ RenderTheme::adjustSearchFieldResultsDecorationStyle(styleResolver, style, e);
+}
+
+bool RenderThemeQStyle::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& pi, const IntRect& r)
+{
+ notImplemented();
+ return RenderTheme::paintSearchFieldResultsDecoration(o, pi, r);
+}
+
+#ifndef QT_NO_SPINBOX
+
+bool RenderThemeQStyle::paintInnerSpinButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ StylePainterQStyle p(this, paintInfo, o);
+ if (!p.isValid())
+ return true;
+
+ p.styleOption.rect = rect;
+ p.paintInnerSpinButton(isSpinUpButtonPartPressed(o));
+ return false;
+}
+#endif
+
+ControlPart RenderThemeQStyle::initializeCommonQStyleOptions(QStyleFacadeOption &option, RenderObject* o) const
+{
+ // Default bits: no focus, no mouse over
+ option.state &= ~(QStyleFacade::State_HasFocus | QStyleFacade::State_MouseOver);
+
+ if (isReadOnlyControl(o))
+ // Readonly is supported on textfields.
+ option.state |= QStyleFacade::State_ReadOnly;
+
+ option.direction = Qt::LeftToRight;
+
+ if (isHovered(o))
+ option.state |= QStyleFacade::State_MouseOver;
+
+ setPaletteFromPageClientIfExists(option.palette);
+
+ if (!isEnabled(o)) {
+ option.palette.setCurrentColorGroup(QPalette::Disabled);
+ option.state &= ~QStyleFacade::State_Enabled;
+ }
+
+ RenderStyle* style = o->style();
+ if (!style)
+ return NoControlPart;
+
+ ControlPart result = style->appearance();
+ if (supportsFocus(result) && isFocused(o)) {
+ option.state |= QStyleFacade::State_HasFocus;
+ option.state |= QStyleFacade::State_KeyboardFocusChange;
+ }
+
+ if (style->direction() == WebCore::RTL)
+ option.direction = Qt::RightToLeft;
+
+ switch (result) {
+ case PushButtonPart:
+ case SquareButtonPart:
+ case ButtonPart:
+ case ButtonBevelPart:
+ case ListItemPart:
+ case MenulistButtonPart:
+ case InnerSpinButtonPart:
+ case SearchFieldResultsButtonPart:
+ case SearchFieldCancelButtonPart: {
+ if (isPressed(o))
+ option.state |= QStyleFacade::State_Sunken;
+ else if (result == PushButtonPart || result == ButtonPart)
+ option.state |= QStyleFacade::State_Raised;
+ break;
+ }
+ case RadioPart:
+ case CheckboxPart:
+ option.state |= (isChecked(o) ? QStyleFacade::State_On : QStyleFacade::State_Off);
+ }
+
+ return result;
+}
+
+void RenderThemeQStyle::adjustSliderThumbSize(RenderStyle* style, Element* element) const
+{
+ const ControlPart part = style->appearance();
+ if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
+ Qt::Orientation orientation = Qt::Horizontal;
+ if (part == SliderThumbVerticalPart)
+ orientation = Qt::Vertical;
+
+ int length = m_qStyle->sliderLength(orientation);
+ int thickness = m_qStyle->sliderThickness(orientation);
+ if (orientation == Qt::Vertical) {
+ style->setWidth(Length(thickness, Fixed));
+ style->setHeight(Length(length, Fixed));
+ } else {
+ style->setWidth(Length(length, Fixed));
+ style->setHeight(Length(thickness, Fixed));
+ }
+ } else
+ RenderThemeQt::adjustSliderThumbSize(style, element);
+}
+
+}
+
+// vim: ts=4 sw=4 et
diff --git a/Source/WebCore/platform/qt/RenderThemeQStyle.h b/Source/WebCore/platform/qt/RenderThemeQStyle.h
new file mode 100644
index 000000000..08c18b971
--- /dev/null
+++ b/Source/WebCore/platform/qt/RenderThemeQStyle.h
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the theme implementation for form controls in WebCore.
+ *
+ * Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef RenderThemeQStyle_h
+#define RenderThemeQStyle_h
+
+#include "QStyleFacade.h"
+#include "RenderThemeQt.h"
+
+namespace WebCore {
+
+class ScrollbarThemeQStyle;
+
+class Page;
+class QStyleFacade;
+struct QStyleFacadeOption;
+
+typedef QStyleFacade* (*QtStyleFactoryFunction)(Page*);
+
+class RenderThemeQStyle : public RenderThemeQt {
+private:
+ friend class StylePainterQStyle;
+
+ RenderThemeQStyle(Page*);
+ virtual ~RenderThemeQStyle();
+
+public:
+ static PassRefPtr<RenderTheme> create(Page*);
+
+ static void setStyleFactoryFunction(QtStyleFactoryFunction);
+ static QtStyleFactoryFunction styleFactory();
+
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
+
+ QStyleFacade* qStyle() { return m_qStyle.get(); }
+
+protected:
+ virtual void adjustButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
+ virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&);
+
+ virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&);
+
+ virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustTextAreaStyle(StyleResolver*, RenderStyle*, Element*) const;
+
+ virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&);
+
+ virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
+
+#if ENABLE(PROGRESS_ELEMENT)
+ // Returns the duration of the animation for the progress bar.
+ virtual double animationDurationForProgressBar(RenderProgress*) const;
+ virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&);
+#endif
+
+ virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSliderTrackStyle(StyleResolver*, RenderStyle*, Element*) const;
+
+ virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSliderThumbStyle(StyleResolver*, RenderStyle*, Element*) const;
+
+ virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&);
+
+ virtual void adjustSearchFieldDecorationStyle(StyleResolver*, RenderStyle*, Element*) const;
+ virtual bool paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&);
+
+ virtual void adjustSearchFieldResultsDecorationStyle(StyleResolver*, RenderStyle*, Element*) const;
+ virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&);
+
+#ifndef QT_NO_SPINBOX
+ virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&);
+#endif
+
+protected:
+ virtual void computeSizeBasedOnStyle(RenderStyle*) const;
+
+ virtual QSharedPointer<StylePainter> getStylePainter(const PaintInfo&);
+
+ virtual QRect inflateButtonRect(const QRect& originalRect) const;
+
+ virtual void setPopupPadding(RenderStyle*) const;
+
+ virtual QPalette colorPalette() const;
+
+private:
+ ControlPart initializeCommonQStyleOptions(QStyleFacadeOption&, RenderObject*) const;
+
+ void setButtonPadding(RenderStyle*) const;
+
+ void setPaletteFromPageClientIfExists(QPalette&) const;
+
+#ifdef Q_OS_MAC
+ int m_buttonFontPixelSize;
+#endif
+
+ OwnPtr<QStyleFacade> m_qStyle;
+};
+
+class StylePainterQStyle : public StylePainter {
+public:
+ explicit StylePainterQStyle(RenderThemeQStyle*, const PaintInfo&, RenderObject*);
+ explicit StylePainterQStyle(ScrollbarThemeQStyle*, GraphicsContext*);
+
+ bool isValid() const { return qStyle && qStyle->isValid() && StylePainter::isValid(); }
+
+ QStyleFacade* qStyle;
+ QStyleFacadeOption styleOption;
+ ControlPart appearance;
+
+ void paintButton(QStyleFacade::ButtonType type)
+ { qStyle->paintButton(painter, type, styleOption); }
+ void paintTextField()
+ { qStyle->paintTextField(painter, styleOption); }
+ void paintComboBox()
+ { qStyle->paintComboBox(painter, styleOption); }
+ void paintComboBoxArrow()
+ { qStyle->paintComboBoxArrow(painter, styleOption); }
+ void paintSliderTrack()
+ { qStyle->paintSliderTrack(painter, styleOption); }
+ void paintSliderThumb()
+ { qStyle->paintSliderThumb(painter, styleOption); }
+ void paintInnerSpinButton(bool spinBoxUp)
+ { qStyle->paintInnerSpinButton(painter, styleOption, spinBoxUp); }
+ void paintProgressBar(double progress, double animationProgress)
+ { qStyle->paintProgressBar(painter, styleOption, progress, animationProgress); }
+ void paintScrollCorner(const QRect& rect)
+ { qStyle->paintScrollCorner(painter, rect); }
+ void paintScrollBar()
+ { qStyle->paintScrollBar(painter, styleOption); }
+
+private:
+ void init(GraphicsContext*);
+
+ Q_DISABLE_COPY(StylePainterQStyle)
+};
+
+}
+
+#endif // RenderThemeQStyle_h
diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp
index 1de8153a3..af36a4f7a 100644
--- a/Source/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp
@@ -60,10 +60,10 @@
#include "UserAgentStyleSheets.h"
#include <wtf/text/StringBuilder.h>
-#include <QGuiApplication>
#include <QColor>
#include <QFile>
#include <QFontMetrics>
+#include <QGuiApplication>
#include <QStyleHints>
diff --git a/Source/WebCore/platform/qt/RunLoopQt.cpp b/Source/WebCore/platform/qt/RunLoopQt.cpp
index 2a87e2fc8..501bd5c12 100644
--- a/Source/WebCore/platform/qt/RunLoopQt.cpp
+++ b/Source/WebCore/platform/qt/RunLoopQt.cpp
@@ -109,7 +109,7 @@ void RunLoop::TimerBase::timerFired(RunLoop* runLoop, int ID)
{
TimerMap::iterator it = runLoop->m_activeTimers.find(ID);
ASSERT(it != runLoop->m_activeTimers.end());
- TimerBase* timer = it->second;
+ TimerBase* timer = it->value;
if (!timer->m_isRepeating) {
// Stop the timer (calling stop would need another hash table lookup).
diff --git a/Source/WebCore/platform/qt/ScrollbarThemeQStyle.cpp b/Source/WebCore/platform/qt/ScrollbarThemeQStyle.cpp
new file mode 100644
index 000000000..ac0dc3844
--- /dev/null
+++ b/Source/WebCore/platform/qt/ScrollbarThemeQStyle.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * 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 "ScrollbarThemeQStyle.h"
+
+#include "GraphicsContext.h"
+#include "PlatformMouseEvent.h"
+#include "RenderThemeQStyle.h"
+#include "ScrollView.h"
+#include "Scrollbar.h"
+
+namespace WebCore {
+
+ScrollbarThemeQStyle::ScrollbarThemeQStyle()
+{
+ m_qStyle = adoptPtr(RenderThemeQStyle::styleFactory()(/*page*/ 0));
+}
+
+ScrollbarThemeQStyle::~ScrollbarThemeQStyle()
+{
+}
+
+static QStyleFacade::SubControl scPart(const ScrollbarPart& part)
+{
+ switch (part) {
+ case NoPart:
+ return QStyleFacade::SC_None;
+ case BackButtonStartPart:
+ case BackButtonEndPart:
+ return QStyleFacade::SC_ScrollBarSubLine;
+ case BackTrackPart:
+ return QStyleFacade::SC_ScrollBarSubPage;
+ case ThumbPart:
+ return QStyleFacade::SC_ScrollBarSlider;
+ case ForwardTrackPart:
+ return QStyleFacade::SC_ScrollBarAddPage;
+ case ForwardButtonStartPart:
+ case ForwardButtonEndPart:
+ return QStyleFacade::SC_ScrollBarAddLine;
+ }
+
+ return QStyleFacade::SC_None;
+}
+
+static ScrollbarPart scrollbarPart(const QStyleFacade::SubControl& sc)
+{
+ switch (sc) {
+ case QStyleFacade::SC_None:
+ return NoPart;
+ case QStyleFacade::SC_ScrollBarSubLine:
+ return BackButtonStartPart;
+ case QStyleFacade::SC_ScrollBarSubPage:
+ return BackTrackPart;
+ case QStyleFacade::SC_ScrollBarSlider:
+ return ThumbPart;
+ case QStyleFacade::SC_ScrollBarAddPage:
+ return ForwardTrackPart;
+ case QStyleFacade::SC_ScrollBarAddLine:
+ return ForwardButtonStartPart;
+ }
+ return NoPart;
+}
+
+static QStyleFacadeOption initSliderStyleOption(ScrollbarThemeClient* scrollbar, QObject* widget = 0)
+{
+ QStyleFacadeOption opt;
+ if (widget) {
+ opt.palette = widget->property("palette").value<QPalette>();
+ opt.rect = widget->property("rect").value<QRect>();
+ opt.direction = static_cast<Qt::LayoutDirection>(widget->property("layoutDirection").toInt());
+ } else
+ opt.state |= QStyleFacade::State_Active;
+
+ opt.state &= ~QStyleFacade::State_HasFocus;
+
+ opt.rect = scrollbar->frameRect();
+ if (scrollbar->enabled())
+ opt.state |= QStyleFacade::State_Enabled;
+ if (scrollbar->controlSize() != RegularScrollbar)
+ opt.state |= QStyleFacade::State_Mini;
+ opt.slider.orientation = (scrollbar->orientation() == VerticalScrollbar) ? Qt::Vertical : Qt::Horizontal;
+
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ opt.state |= QStyleFacade::State_Horizontal;
+ else
+ opt.state &= ~QStyleFacade::State_Horizontal;
+
+ opt.slider.value = scrollbar->value();
+ opt.slider.position = opt.slider.value;
+ opt.slider.pageStep = scrollbar->pageStep();
+ opt.slider.singleStep = scrollbar->lineStep();
+ opt.slider.minimum = 0;
+ opt.slider.maximum = qMax(0, scrollbar->maximum());
+ ScrollbarPart pressedPart = scrollbar->pressedPart();
+ ScrollbarPart hoveredPart = scrollbar->hoveredPart();
+ if (pressedPart != NoPart) {
+ opt.slider.activeSubControls = scPart(scrollbar->pressedPart());
+ if (pressedPart == BackButtonStartPart || pressedPart == ForwardButtonStartPart
+ || pressedPart == BackButtonEndPart || pressedPart == ForwardButtonEndPart
+ || pressedPart == ThumbPart)
+ opt.state |= QStyleFacade::State_Sunken;
+ } else
+ opt.slider.activeSubControls = scPart(hoveredPart);
+ if (hoveredPart != NoPart)
+ opt.state |= QStyleFacade::State_MouseOver;
+ return opt;
+}
+
+bool ScrollbarThemeQStyle::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* graphicsContext, const IntRect& dirtyRect)
+{
+ if (graphicsContext->updatingControlTints()) {
+ scrollbar->invalidateRect(dirtyRect);
+ return false;
+ }
+
+ StylePainterQStyle p(this, graphicsContext);
+ if (!p.isValid())
+ return true;
+
+ p.painter->save();
+ p.styleOption = initSliderStyleOption(scrollbar, m_qStyle->widgetForPainter(p.painter));
+
+ p.painter->setClipRect(p.styleOption.rect.intersected(dirtyRect), Qt::IntersectClip);
+ p.paintScrollBar();
+ p.painter->restore();
+ return true;
+}
+
+ScrollbarPart ScrollbarThemeQStyle::hitTest(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& evt)
+{
+ QStyleFacadeOption opt = initSliderStyleOption(scrollbar);
+ const QPoint pos = scrollbar->convertFromContainingWindow(evt.position());
+ opt.rect.moveTo(QPoint(0, 0));
+ QStyleFacade::SubControl sc = m_qStyle->hitTestScrollBar(opt, pos);
+ return scrollbarPart(sc);
+}
+
+bool ScrollbarThemeQStyle::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
+{
+ // Middle click centers slider thumb (if supported).
+ return m_qStyle->scrollBarMiddleClickAbsolutePositionStyleHint() && evt.button() == MiddleButton;
+}
+
+void ScrollbarThemeQStyle::invalidatePart(ScrollbarThemeClient* scrollbar, ScrollbarPart)
+{
+ // FIXME: Do more precise invalidation.
+ scrollbar->invalidate();
+}
+
+int ScrollbarThemeQStyle::scrollbarThickness(ScrollbarControlSize controlSize)
+{
+ const bool mini = controlSize != RegularScrollbar;
+ return m_qStyle->scrollBarExtent(mini);
+}
+
+int ScrollbarThemeQStyle::thumbPosition(ScrollbarThemeClient* scrollbar)
+{
+ if (scrollbar->enabled()) {
+ float pos = (float)scrollbar->currentPos() * (trackLength(scrollbar) - thumbLength(scrollbar)) / scrollbar->maximum();
+ return (pos < 1 && pos > 0) ? 1 : pos;
+ }
+ return 0;
+}
+
+int ScrollbarThemeQStyle::thumbLength(ScrollbarThemeClient* scrollbar)
+{
+ QStyleFacadeOption opt = initSliderStyleOption(scrollbar);
+ QRect thumb = m_qStyle->scrollBarSubControlRect(opt, QStyleFacade::SC_ScrollBarSlider);
+ return scrollbar->orientation() == HorizontalScrollbar ? thumb.width() : thumb.height();
+}
+
+int ScrollbarThemeQStyle::trackPosition(ScrollbarThemeClient* scrollbar)
+{
+ QStyleFacadeOption opt = initSliderStyleOption(scrollbar);
+ QRect track = m_qStyle->scrollBarSubControlRect(opt, QStyleFacade::SC_ScrollBarGroove);
+ return scrollbar->orientation() == HorizontalScrollbar ? track.x() - scrollbar->x() : track.y() - scrollbar->y();
+}
+
+int ScrollbarThemeQStyle::trackLength(ScrollbarThemeClient* scrollbar)
+{
+ QStyleFacadeOption opt = initSliderStyleOption(scrollbar);
+ QRect track = m_qStyle->scrollBarSubControlRect(opt, QStyleFacade::SC_ScrollBarGroove);
+ return scrollbar->orientation() == HorizontalScrollbar ? track.width() : track.height();
+}
+
+void ScrollbarThemeQStyle::paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& rect)
+{
+ StylePainterQStyle p(this, context);
+ if (!p.isValid())
+ return;
+
+ p.paintScrollCorner(rect);
+}
+
+}
+
diff --git a/Source/WebCore/platform/text/LocalizedDateNone.cpp b/Source/WebCore/platform/qt/ScrollbarThemeQStyle.h
index 14ca33906..e04afad12 100644
--- a/Source/WebCore/platform/text/LocalizedDateNone.cpp
+++ b/Source/WebCore/platform/qt/ScrollbarThemeQStyle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,23 +23,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "LocalizedDate.h"
+#ifndef ScrollbarThemeQStyle_h
+#define ScrollbarThemeQStyle_h
-#include <limits>
+#include "ScrollbarTheme.h"
-using namespace std;
+#include <QtCore/qglobal.h>
namespace WebCore {
-double parseLocalizedDate(const String&, DateComponents::Type)
-{
- return numeric_limits<double>::quiet_NaN();
-}
+class QStyleFacade;
-String formatLocalizedDate(const DateComponents&)
-{
- return String();
-}
+class ScrollbarThemeQStyle : public ScrollbarTheme {
+public:
+ ScrollbarThemeQStyle();
+ virtual ~ScrollbarThemeQStyle();
+
+ virtual bool paint(ScrollbarThemeClient*, GraphicsContext*, const IntRect& dirtyRect);
+ virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect& cornerRect);
+
+ virtual ScrollbarPart hitTest(ScrollbarThemeClient*, const PlatformMouseEvent&);
+
+ virtual bool shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent&);
+
+ virtual void invalidatePart(ScrollbarThemeClient*, ScrollbarPart);
-} // namespace WebCore
+ virtual int thumbPosition(ScrollbarThemeClient*);
+ virtual int thumbLength(ScrollbarThemeClient*);
+ virtual int trackPosition(ScrollbarThemeClient*);
+ virtual int trackLength(ScrollbarThemeClient*);
+
+ virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+
+ QStyleFacade* qStyle() { return m_qStyle.get(); }
+
+private:
+ OwnPtr<QStyleFacade> m_qStyle;
+};
+
+}
+#endif
diff --git a/Source/WebCore/platform/sql/SQLiteDatabase.cpp b/Source/WebCore/platform/sql/SQLiteDatabase.cpp
index 8ab626b12..2418fc12c 100644
--- a/Source/WebCore/platform/sql/SQLiteDatabase.cpp
+++ b/Source/WebCore/platform/sql/SQLiteDatabase.cpp
@@ -45,6 +45,7 @@ const int SQLResultRow = SQLITE_ROW;
const int SQLResultSchema = SQLITE_SCHEMA;
const int SQLResultFull = SQLITE_FULL;
const int SQLResultInterrupt = SQLITE_INTERRUPT;
+const int SQLResultConstraint = SQLITE_CONSTRAINT;
static const char notOpenErrorMessage[] = "database is not open";
@@ -57,6 +58,7 @@ SQLiteDatabase::SQLiteDatabase()
, m_interrupted(false)
, m_openError(SQLITE_ERROR)
, m_openErrorMessage()
+ , m_lastChangesCount(0)
{
}
@@ -320,11 +322,20 @@ int64_t SQLiteDatabase::lastInsertRowID()
return sqlite3_last_insert_rowid(m_db);
}
+void SQLiteDatabase::updateLastChangesCount()
+{
+ if (!m_db)
+ return;
+
+ m_lastChangesCount = sqlite3_total_changes(m_db);
+}
+
int SQLiteDatabase::lastChanges()
{
if (!m_db)
return 0;
- return sqlite3_changes(m_db);
+
+ return sqlite3_total_changes(m_db) - m_lastChangesCount;
}
int SQLiteDatabase::lastError()
diff --git a/Source/WebCore/platform/sql/SQLiteDatabase.h b/Source/WebCore/platform/sql/SQLiteDatabase.h
index 40ee81b0e..f15508c40 100644
--- a/Source/WebCore/platform/sql/SQLiteDatabase.h
+++ b/Source/WebCore/platform/sql/SQLiteDatabase.h
@@ -50,6 +50,7 @@ extern const int SQLResultRow;
extern const int SQLResultSchema;
extern const int SQLResultFull;
extern const int SQLResultInterrupt;
+extern const int SQLResultConstraint;
class SQLiteDatabase {
WTF_MAKE_NONCOPYABLE(SQLiteDatabase);
@@ -64,6 +65,8 @@ public:
void interrupt();
bool isInterrupted();
+ void updateLastChangesCount();
+
bool executeCommand(const String&);
bool returnsAtLeastOneResult(const String&);
@@ -157,6 +160,8 @@ private:
int m_openError;
CString m_openErrorMessage;
+
+ int m_lastChangesCount;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/sql/SQLiteStatement.cpp b/Source/WebCore/platform/sql/SQLiteStatement.cpp
index d308872d5..3c7e949b8 100644
--- a/Source/WebCore/platform/sql/SQLiteStatement.cpp
+++ b/Source/WebCore/platform/sql/SQLiteStatement.cpp
@@ -101,6 +101,11 @@ int SQLiteStatement::step()
if (!m_statement)
return SQLITE_OK;
+
+ // The database needs to update its last changes count before each statement
+ // in order to compute properly the lastChanges() return value.
+ m_database.updateLastChangesCount();
+
LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data());
int error = sqlite3_step(m_statement);
if (error != SQLITE_DONE && error != SQLITE_ROW) {
diff --git a/Source/WebCore/platform/text/DateTimeFormat.cpp b/Source/WebCore/platform/text/DateTimeFormat.cpp
index 6de7fdcde..2b1c28c68 100644
--- a/Source/WebCore/platform/text/DateTimeFormat.cpp
+++ b/Source/WebCore/platform/text/DateTimeFormat.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "DateTimeFormat.h"
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include <wtf/ASCIICType.h>
#include <wtf/text/StringBuilder.h>
@@ -55,7 +55,7 @@ static const DateTimeFormat::FieldType lowerCaseToFieldTypeMap[26] = {
DateTimeFormat::FieldTypeInvalid, // t
DateTimeFormat::FieldTypeExtendedYear, // u
DateTimeFormat::FieldTypeNonLocationZone, // v
- DateTimeFormat::FieldTypeWeekOfMonth, // w
+ DateTimeFormat::FieldTypeWeekOfYear, // w
DateTimeFormat::FieldTypeInvalid, // x
DateTimeFormat::FieldTypeYear, // y
DateTimeFormat::FieldTypeZone, // z
@@ -84,7 +84,7 @@ static const DateTimeFormat::FieldType upperCaseToFieldTypeMap[26] = {
DateTimeFormat::FieldTypeInvalid, // T
DateTimeFormat::FieldTypeInvalid, // U
DateTimeFormat::FieldTypeInvalid, // V
- DateTimeFormat::FieldTypeWeekOfYear, // W
+ DateTimeFormat::FieldTypeWeekOfMonth, // W
DateTimeFormat::FieldTypeInvalid, // X
DateTimeFormat::FieldTypeYearOfWeekOfYear, // Y
DateTimeFormat::FieldTypeRFC822Zone, // Z
diff --git a/Source/WebCore/platform/text/DateTimeFormat.h b/Source/WebCore/platform/text/DateTimeFormat.h
index b7b740290..f5ff0038f 100644
--- a/Source/WebCore/platform/text/DateTimeFormat.h
+++ b/Source/WebCore/platform/text/DateTimeFormat.h
@@ -26,7 +26,7 @@
#ifndef DateTimeFormat_h
#define DateTimeFormat_h
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -57,8 +57,8 @@ public:
FieldTypeMonthStandAlone = 'L',
// Week: 42
- FieldTypeWeekOfYear = 'W',
- FieldTypeWeekOfMonth = 'w',
+ FieldTypeWeekOfYear = 'w',
+ FieldTypeWeekOfMonth = 'W',
// Day: 12
FieldTypeDayOfMonth = 'd',
diff --git a/Source/WebCore/platform/text/LocaleICU.cpp b/Source/WebCore/platform/text/LocaleICU.cpp
index ae9d1cbd1..ce5f0afc4 100644
--- a/Source/WebCore/platform/text/LocaleICU.cpp
+++ b/Source/WebCore/platform/text/LocaleICU.cpp
@@ -33,6 +33,7 @@
#include "LocalizedStrings.h"
#include <limits>
+#include <unicode/uloc.h>
#include <wtf/DateMath.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/StringBuilder.h>
@@ -56,7 +57,7 @@ LocaleICU::LocaleICU(const char* locale)
#if ENABLE(CALENDAR_PICKER)
, m_firstDayOfWeek(0)
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
, m_mediumTimeFormat(0)
, m_shortTimeFormat(0)
, m_didCreateTimeFormat(false)
@@ -68,7 +69,7 @@ LocaleICU::~LocaleICU()
{
unum_close(m_numberFormat);
udat_close(m_shortDateFormat);
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
udat_close(m_mediumTimeFormat);
udat_close(m_shortTimeFormat);
#endif
@@ -79,17 +80,6 @@ PassOwnPtr<LocaleICU> LocaleICU::create(const char* localeString)
return adoptPtr(new LocaleICU(localeString));
}
-PassOwnPtr<LocaleICU> LocaleICU::createForCurrentLocale()
-{
- return adoptPtr(new LocaleICU(0));
-}
-
-LocaleICU* LocaleICU::currentLocale()
-{
- static LocaleICU* currentLocale = LocaleICU::createForCurrentLocale().leakPtr();
- return currentLocale;
-}
-
String LocaleICU::decimalSymbol(UNumberFormatSymbol symbol)
{
UErrorCode status = U_ZERO_ERROR;
@@ -164,8 +154,10 @@ UDateFormat* LocaleICU::openDateFormat(UDateFormatStyle timeStyle, UDateFormatSt
return udat_open(timeStyle, dateStyle, m_locale.data(), gmtTimezone, WTF_ARRAY_LENGTH(gmtTimezone), 0, -1, &status);
}
-double LocaleICU::parseLocalizedDate(const String& input)
+double LocaleICU::parseDateTime(const String& input, DateComponents::Type type)
{
+ if (type != DateComponents::Date)
+ return std::numeric_limits<double>::quiet_NaN();
if (!initializeShortDateFormat())
return numeric_limits<double>::quiet_NaN();
if (input.length() > static_cast<unsigned>(numeric_limits<int32_t>::max()))
@@ -180,24 +172,7 @@ double LocaleICU::parseLocalizedDate(const String& input)
return date;
}
-String LocaleICU::formatLocalizedDate(const DateComponents& dateComponents)
-{
- if (!initializeShortDateFormat())
- return String();
- double input = dateComponents.millisecondsSinceEpoch();
- UErrorCode status = U_ZERO_ERROR;
- int32_t length = udat_format(m_shortDateFormat, input, 0, 0, 0, &status);
- if (status != U_BUFFER_OVERFLOW_ERROR)
- return String();
- Vector<UChar> buffer(length);
- status = U_ZERO_ERROR;
- udat_format(m_shortDateFormat, input, buffer.data(), length, 0, &status);
- if (U_FAILURE(status))
- return String();
- return String::adopt(buffer);
-}
-
-#if ENABLE(CALENDAR_PICKER) || ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(CALENDAR_PICKER) || ENABLE(INPUT_MULTIPLE_FIELDS_UI)
static String getDateFormatPattern(const UDateFormat* dateFormat)
{
if (!dateFormat)
@@ -281,7 +256,7 @@ void LocaleICU::initializeLocalizedDateFormatText()
m_localizedDateFormatText = localizeFormat(getDateFormatPattern(m_shortDateFormat));
}
-String LocaleICU::localizedDateFormatText()
+String LocaleICU::dateFormatText()
{
initializeLocalizedDateFormatText();
return m_localizedDateFormatText;
@@ -373,9 +348,15 @@ unsigned LocaleICU::firstDayOfWeek()
initializeCalendar();
return m_firstDayOfWeek;
}
+
+bool LocaleICU::isRTL()
+{
+ UErrorCode status = U_ZERO_ERROR;
+ return uloc_getCharacterOrientation(m_locale.data(), &status) == ULOC_LAYOUT_RTL;
+}
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
static PassOwnPtr<Vector<String> > createFallbackAMPMLabels()
{
OwnPtr<Vector<String> > labels = adoptPtr(new Vector<String>());
@@ -407,6 +388,16 @@ void LocaleICU::initializeDateTimeFormat()
m_didCreateTimeFormat = true;
}
+String LocaleICU::dateFormat()
+{
+ if (!m_dateFormat.isEmpty())
+ return m_dateFormat;
+ if (!initializeShortDateFormat())
+ return ASCIILiteral("dd/MM/yyyy");
+ m_dateFormat = getDateFormatPattern(m_shortDateFormat);
+ return m_dateFormat;
+}
+
String LocaleICU::timeFormat()
{
initializeDateTimeFormat();
diff --git a/Source/WebCore/platform/text/LocaleICU.h b/Source/WebCore/platform/text/LocaleICU.h
index 1cda89f69..a4b8122cb 100644
--- a/Source/WebCore/platform/text/LocaleICU.h
+++ b/Source/WebCore/platform/text/LocaleICU.h
@@ -47,28 +47,27 @@ namespace WebCore {
class LocaleICU : public Localizer {
public:
static PassOwnPtr<LocaleICU> create(const char* localeString);
- static LocaleICU* currentLocale();
virtual ~LocaleICU();
// For LocalizedDate
- double parseLocalizedDate(const String&);
- String formatLocalizedDate(const DateComponents&);
+ virtual double parseDateTime(const String&, DateComponents::Type) OVERRIDE;
#if ENABLE(CALENDAR_PICKER)
- String localizedDateFormatText();
+ virtual String dateFormatText() OVERRIDE;
- const Vector<String>& monthLabels();
- const Vector<String>& weekDayShortLabels();
- unsigned firstDayOfWeek();
+ virtual const Vector<String>& monthLabels() OVERRIDE;
+ virtual const Vector<String>& weekDayShortLabels() OVERRIDE;
+ virtual unsigned firstDayOfWeek() OVERRIDE;
+ virtual bool isRTL() OVERRIDE;
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ virtual String dateFormat() OVERRIDE;
virtual String timeFormat() OVERRIDE;
virtual String shortTimeFormat() OVERRIDE;
virtual const Vector<String>& timeAMPMLabels() OVERRIDE;
#endif
private:
- static PassOwnPtr<LocaleICU> createForCurrentLocale();
explicit LocaleICU(const char*);
String decimalSymbol(UNumberFormatSymbol);
String decimalTextAttribute(UNumberFormatTextAttribute);
@@ -85,11 +84,11 @@ private:
void initializeCalendar();
#endif
-#if ENABLE(CALENDAR_PICKER) || ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(CALENDAR_PICKER) || ENABLE(INPUT_MULTIPLE_FIELDS_UI)
PassOwnPtr<Vector<String> > createLabelVector(const UDateFormat*, UDateFormatSymbolType, int32_t startIndex, int32_t size);
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
void initializeDateTimeFormat();
#endif
@@ -106,7 +105,8 @@ private:
unsigned m_firstDayOfWeek;
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ String m_dateFormat;
UDateFormat* m_mediumTimeFormat;
UDateFormat* m_shortTimeFormat;
Vector<String> m_timeAMPMLabels;
diff --git a/Source/WebCore/platform/text/LocaleNone.cpp b/Source/WebCore/platform/text/LocaleNone.cpp
index fe48c7f79..0ddaf3036 100644
--- a/Source/WebCore/platform/text/LocaleNone.cpp
+++ b/Source/WebCore/platform/text/LocaleNone.cpp
@@ -35,6 +35,14 @@ public:
private:
virtual void initializeLocalizerData() OVERRIDE FINAL;
+ virtual double parseDateTime(const String&, DateComponents::Type) OVERRIDE;
+#if ENABLE(CALENDAR_PICKER)
+ virtual String dateFormatText() OVERRIDE;
+ virtual bool isRTL() OVERRIDE;
+#endif
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ virtual String dateFormat() OVERRIDE;
+#endif
};
PassOwnPtr<Localizer> Localizer::create(const AtomicString&)
@@ -50,4 +58,28 @@ void LocaleNone::initializeLocalizerData()
{
}
+double LocaleNone::parseDateTime(const String&, DateComponents::Type)
+{
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+#if ENABLE(CALENDAR_PICKER)
+String LocaleNone::dateFormatText()
+{
+ return ASCIILiteral("Year-Month-Day");
+}
+
+bool LocaleNone::isRTL()
+{
+ return false;
+}
+#endif
+
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+String LocaleNone::dateFormat()
+{
+ return ASCIILiteral("dd/MM/yyyyy");
+}
+#endif
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp b/Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp
index 909473849..58264907d 100644
--- a/Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp
+++ b/Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp
@@ -166,7 +166,7 @@ UScriptCode scriptNameToCode(const String& scriptName)
HashMap<String, UScriptCode>::iterator it = scriptNameCodeMap.find(scriptName.lower());
if (it != scriptNameCodeMap.end())
- return it->second;
+ return it->value;
return USCRIPT_INVALID_CODE;
}
@@ -389,7 +389,7 @@ UScriptCode localeToScriptCodeForFontSelection(const String& locale)
while (!canonicalLocale.isEmpty()) {
HashMap<String, UScriptCode>::iterator it = localeScriptMap.find(canonicalLocale);
if (it != localeScriptMap.end())
- return it->second;
+ return it->value;
size_t pos = canonicalLocale.reverseFind('_');
if (pos == notFound)
break;
diff --git a/Source/WebCore/platform/text/LocaleWin.cpp b/Source/WebCore/platform/text/LocaleWin.cpp
index 9925776e9..097b09302 100644
--- a/Source/WebCore/platform/text/LocaleWin.cpp
+++ b/Source/WebCore/platform/text/LocaleWin.cpp
@@ -32,7 +32,7 @@
#include "LocaleWin.h"
#include "DateComponents.h"
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "DateTimeFormat.h"
#endif
#include "Language.h"
@@ -119,12 +119,6 @@ PassOwnPtr<LocaleWin> LocaleWin::create(LCID lcid)
return adoptPtr(new LocaleWin(lcid));
}
-LocaleWin* LocaleWin::currentLocale()
-{
- static LocaleWin* currentLocale = LocaleWin::create(LCIDFromLocale(defaultLanguage())).leakPtr();
- return currentLocale;
-}
-
LocaleWin::~LocaleWin()
{
}
@@ -240,14 +234,18 @@ static Vector<DateFormatToken> parseDateFormat(const String format)
Vector<DateFormatToken> tokens;
StringBuilder literalBuffer;
bool inQuote = false;
+ bool lastQuoteCanBeLiteral = false;
for (unsigned i = 0; i < format.length(); ++i) {
UChar ch = format[i];
if (inQuote) {
if (ch == '\'') {
inQuote = false;
ASSERT(i);
- if (format[i - 1] == '\'')
+ if (lastQuoteCanBeLiteral && format[i - 1] == '\'') {
literalBuffer.append('\'');
+ lastQuoteCanBeLiteral = false;
+ } else
+ lastQuoteCanBeLiteral = true;
} else
literalBuffer.append(ch);
continue;
@@ -255,8 +253,11 @@ static Vector<DateFormatToken> parseDateFormat(const String format)
if (ch == '\'') {
inQuote = true;
- if (i > 0 && format[i - 1] == '\'')
+ if (lastQuoteCanBeLiteral && i > 0 && format[i - 1] == '\'') {
literalBuffer.append(ch);
+ lastQuoteCanBeLiteral = false;
+ } else
+ lastQuoteCanBeLiteral = true;
} else if (isYearSymbol(ch)) {
commitLiteralToken(literalBuffer, tokens);
unsigned count = countContinuousLetters(format, i);
@@ -354,8 +355,10 @@ int LocaleWin::parseNumberOrMonth(const String& input, unsigned& index)
return -1;
}
-double LocaleWin::parseDate(const String& input)
+double LocaleWin::parseDateTime(const String& input, DateComponents::Type type)
{
+ if (type != DateComponents::Date)
+ return std::numeric_limits<double>::quiet_NaN();
ensureShortDateTokens();
return parseDate(m_shortDateTokens, m_baseYear, input);
}
@@ -440,111 +443,6 @@ double LocaleWin::parseDate(const Vector<DateFormatToken>& tokens, int baseYear,
// -------------------------------- Formatting
-inline void LocaleWin::appendNumber(int value, StringBuilder& buffer)
-{
- buffer.append(convertToLocalizedNumber(String::number(value)));
-}
-
-void LocaleWin::appendTwoDigitsNumber(int value, StringBuilder& buffer)
-{
- String numberString = String::number(value);
- if (value < 0 || value >= 10) {
- buffer.append(convertToLocalizedNumber(numberString));
- return;
- }
- StringBuilder numberBuffer;
- numberBuffer.reserveCapacity(1 + numberString.length());
- numberBuffer.append("0");
- numberBuffer.append(numberString);
- buffer.append(convertToLocalizedNumber(numberBuffer.toString()));
-}
-
-void LocaleWin::appendFourDigitsNumber(int value, StringBuilder& buffer)
-{
- String numberString = String::number(value);
- if (value < 0) {
- buffer.append(convertToLocalizedNumber(numberString));
- return;
- }
- StringBuilder numberBuffer;
- numberBuffer.reserveCapacity(3 + numberString.length());
- if (value < 10)
- numberBuffer.append("000");
- else if (value < 100)
- numberBuffer.append("00");
- else if (value < 1000)
- numberBuffer.append("0");
- numberBuffer.append(numberString);
- buffer.append(convertToLocalizedNumber(numberBuffer.toString()));
-}
-
-String LocaleWin::formatDate(const DateComponents& dateComponents)
-{
- ensureShortDateTokens();
- return formatDate(m_shortDateTokens, m_baseYear, dateComponents.fullYear(), dateComponents.month(), dateComponents.monthDay());
-}
-
-String LocaleWin::formatDate(const String& format, int baseYear, int year, int month, int day)
-{
- return formatDate(parseDateFormat(format), baseYear, year, month, day);
-}
-
-String LocaleWin::formatDate(const Vector<DateFormatToken>& tokens, int baseYear, int year, int month, int day)
-{
- ensureShortMonthLabels();
- ensureMonthLabels();
- StringBuilder buffer;
- for (unsigned i = 0; i < tokens.size(); ++i) {
- switch (tokens[i].type) {
- case DateFormatToken::Literal:
- buffer.append(tokens[i].data);
- break;
- case DateFormatToken::Day1:
- appendNumber(day, buffer);
- break;
- case DateFormatToken::Day2:
- appendTwoDigitsNumber(day, buffer);
- break;
- case DateFormatToken::Month1:
- appendNumber(month + 1, buffer);
- break;
- case DateFormatToken::Month2:
- appendTwoDigitsNumber(month + 1, buffer);
- break;
- case DateFormatToken::Month3:
- if (0 <= month && month < static_cast<int>(m_shortMonthLabels.size()))
- buffer.append(m_shortMonthLabels[month]);
- else
- appendNumber(month + 1, buffer);
- break;
- case DateFormatToken::Month4:
- if (0 <= month && month < static_cast<int>(m_monthLabels.size()))
- buffer.append(m_monthLabels[month]);
- else
- appendNumber(month + 1, buffer);
- break;
- case DateFormatToken::Year1: {
- if (baseYear - 4 <= year && year <= baseYear + 5)
- appendNumber(year % 10, buffer);
- else
- appendFourDigitsNumber(year, buffer);
- break;
- }
- case DateFormatToken::Year2: {
- if (baseYear - 49 <= year && year <= baseYear + 50)
- appendTwoDigitsNumber(year % 100, buffer);
- else
- appendFourDigitsNumber(year, buffer);
- break;
- }
- case DateFormatToken::Year4:
- appendFourDigitsNumber(year, buffer);
- break;
- }
- }
- return buffer.toString();
-}
-
void LocaleWin::ensureShortDateTokens()
{
if (!m_shortDateTokens.isEmpty())
@@ -665,9 +563,90 @@ const Vector<String>& LocaleWin::weekDayShortLabels()
ensureWeekDayShortLabels();
return m_weekDayShortLabels;
}
+
+unsigned LocaleWin::firstDayOfWeek()
+{
+ return m_firstDayOfWeek;
+}
+
+bool LocaleWin::isRTL()
+{
+ WTF::Unicode::Direction dir = WTF::Unicode::direction(monthLabels()[0][0]);
+ return dir == WTF::Unicode::RightToLeft || dir == WTF::Unicode::RightToLeftArabic;
+}
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+static void appendAsLDMLLiteral(const String& literal, StringBuilder& buffer)
+{
+ if (literal.length() <= 0)
+ return;
+
+ if (literal.find('\'') == notFound) {
+ buffer.append("'");
+ buffer.append(literal);
+ buffer.append("'");
+ return;
+ }
+
+ for (unsigned i = 0; i < literal.length(); ++i) {
+ if (literal[i] == '\'')
+ buffer.append("''");
+ else {
+ String escaped = literal.substring(i);
+ escaped.replace(ASCIILiteral("'"), ASCIILiteral("''"));
+ buffer.append("'");
+ buffer.append(escaped);
+ buffer.append("'");
+ return;
+ }
+ }
+}
+
+static String convertWindowsDateFormatToLDML(const Vector<DateFormatToken>& tokens)
+{
+ StringBuilder buffer;
+ for (unsigned i = 0; i < tokens.size(); ++i) {
+ switch (tokens[i].type) {
+ case DateFormatToken::Literal:
+ appendAsLDMLLiteral(tokens[i].data, buffer);
+ break;
+
+ case DateFormatToken::Day2:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeDayOfMonth));
+ // Fallthrough.
+ case DateFormatToken::Day1:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeDayOfMonth));
+ break;
+
+ case DateFormatToken::Month4:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeMonth));
+ // Fallthrough.
+ case DateFormatToken::Month3:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeMonth));
+ // Fallthrough.
+ case DateFormatToken::Month2:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeMonth));
+ // Fallthrough.
+ case DateFormatToken::Month1:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeMonth));
+ break;
+
+ case DateFormatToken::Year4:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeYear));
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeYear));
+ // Fallthrough.
+ case DateFormatToken::Year2:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeYear));
+ // Fallthrough.
+ case DateFormatToken::Year1:
+ buffer.append(static_cast<char>(DateTimeFormat::FieldTypeYear));
+ break;
+ }
+ }
+ return buffer.toString();
+}
+
static DateTimeFormat::FieldType mapCharacterToDateTimeFieldType(UChar ch)
{
switch (ch) {
@@ -720,6 +699,20 @@ static String convertWindowsTimeFormatToLDML(const String& windowsTimeFormat)
return builder.toString();
}
+String LocaleWin::dateFormat()
+{
+ if (!m_dateFormat.isEmpty())
+ return m_dateFormat;
+ ensureShortDateTokens();
+ m_dateFormat = convertWindowsDateFormatToLDML(m_shortDateTokens);
+ return m_dateFormat;
+}
+
+String LocaleWin::dateFormat(const String& windowsFormat)
+{
+ return convertWindowsDateFormatToLDML(parseDateFormat(windowsFormat));
+}
+
String LocaleWin::timeFormat()
{
if (m_localizedTimeFormatText.isEmpty())
diff --git a/Source/WebCore/platform/text/LocaleWin.h b/Source/WebCore/platform/text/LocaleWin.h
index ab3acd760..21ad7bf5f 100644
--- a/Source/WebCore/platform/text/LocaleWin.h
+++ b/Source/WebCore/platform/text/LocaleWin.h
@@ -45,18 +45,18 @@ struct DateFormatToken;
class LocaleWin : public Localizer {
public:
static PassOwnPtr<LocaleWin> create(LCID);
- static LocaleWin* currentLocale();
~LocaleWin();
- double parseDate(const String&);
- String formatDate(const DateComponents&);
+ virtual double parseDateTime(const String&, DateComponents::Type) OVERRIDE;
#if ENABLE(CALENDAR_PICKER)
- String dateFormatText();
- const Vector<String>& monthLabels();
- const Vector<String>& weekDayShortLabels();
- unsigned firstDayOfWeek() { return m_firstDayOfWeek; }
+ virtual String dateFormatText() OVERRIDE;
+ virtual const Vector<String>& monthLabels() OVERRIDE;
+ virtual const Vector<String>& weekDayShortLabels() OVERRIDE;
+ virtual unsigned firstDayOfWeek() OVERRIDE;
+ virtual bool isRTL() OVERRIDE;
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ virtual String dateFormat() OVERRIDE;
virtual String timeFormat() OVERRIDE;
virtual String shortTimeFormat() OVERRIDE;
virtual const Vector<String>& timeAMPMLabels() OVERRIDE;
@@ -66,6 +66,9 @@ public:
double parseDate(const String& format, int baseYear, const String& input);
String formatDate(const String& format, int baseYear, int year, int month, int day);
static String dateFormatText(const String& format, const String& yearText, const String& monthText, const String& dayText);
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ static String dateFormat(const String&);
+#endif
private:
explicit LocaleWin(LCID);
@@ -93,6 +96,9 @@ private:
Vector<DateFormatToken> m_shortDateTokens;
Vector<String> m_shortMonthLabels;
Vector<String> m_monthLabels;
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ String m_dateFormat;
+#endif
#if ENABLE(CALENDAR_PICKER)
Vector<String> m_weekDayShortLabels;
unsigned m_firstDayOfWeek;
diff --git a/Source/WebCore/platform/text/LocalizedDate.h b/Source/WebCore/platform/text/LocalizedDate.h
deleted file mode 100644
index 7449e5b1d..000000000
--- a/Source/WebCore/platform/text/LocalizedDate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 LocalizedDate_h
-#define LocalizedDate_h
-
-#include "DateComponents.h"
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-// Parses a string representation of a date string localized
-// for the browser's current locale for a particular date type.
-// If the input string is not valid or an implementation doesn't
-// support localized dates, this function returns NaN. If the
-// input string is valid this function returns the number
-// of milliseconds since 1970-01-01 00:00:00.000 UTC.
-double parseLocalizedDate(const String&, DateComponents::Type);
-
-// Serializes the specified date into a formatted date string
-// to display to the user. If an implementation doesn't support
-// localized dates the function should return an empty string.
-String formatLocalizedDate(const DateComponents& dateComponents);
-
-#if ENABLE(CALENDAR_PICKER)
-String localizedDateFormatText();
-
-// Returns a vector of string of which size is 12. The first item is a
-// localized string of January, and the last item is a localized
-// string of December. These strings should not be abbreviations.
-const Vector<String>& monthLabels();
-
-// Returns a vector of string of which size is 7. The first item is a
-// localized short string of Monday, and the last item is a localized
-// short string of Saturday. These strings should be short.
-const Vector<String>& weekDayShortLabels();
-
-// The first day of a week. 0 is Sunday, and 6 is Saturday.
-unsigned firstDayOfWeek();
-#endif
-
-} // namespace WebCore
-
-#endif // LocalizedDate_h
diff --git a/Source/WebCore/platform/text/LocalizedDateICU.cpp b/Source/WebCore/platform/text/LocalizedDateICU.cpp
deleted file mode 100644
index 10cb6f132..000000000
--- a/Source/WebCore/platform/text/LocalizedDateICU.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "LocalizedDate.h"
-
-#include "LocaleICU.h"
-#include <limits>
-
-using namespace std;
-
-namespace WebCore {
-
-double parseLocalizedDate(const String& input, DateComponents::Type type)
-{
- switch (type) {
- case DateComponents::Date:
- return LocaleICU::currentLocale()->parseLocalizedDate(input);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return numeric_limits<double>::quiet_NaN();
-}
-
-String formatLocalizedDate(const DateComponents& dateComponents)
-{
- switch (dateComponents.type()) {
- case DateComponents::Date:
- return LocaleICU::currentLocale()->formatLocalizedDate(dateComponents);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return String();
-}
-
-#if ENABLE(CALENDAR_PICKER)
-String localizedDateFormatText()
-{
- return LocaleICU::currentLocale()->localizedDateFormatText();
-}
-
-const Vector<String>& monthLabels()
-{
- return LocaleICU::currentLocale()->monthLabels();
-}
-
-const Vector<String>& weekDayShortLabels()
-{
- return LocaleICU::currentLocale()->weekDayShortLabels();
-}
-
-unsigned firstDayOfWeek()
-{
- return LocaleICU::currentLocale()->firstDayOfWeek();
-}
-#endif
-
-}
diff --git a/Source/WebCore/platform/text/LocalizedDateWin.cpp b/Source/WebCore/platform/text/LocalizedDateWin.cpp
deleted file mode 100644
index bd8f367f3..000000000
--- a/Source/WebCore/platform/text/LocalizedDateWin.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "LocalizedDate.h"
-
-#include "LocaleWin.h"
-#include <limits>
-
-using namespace std;
-
-namespace WebCore {
-
-double parseLocalizedDate(const String& input, DateComponents::Type type)
-{
- switch (type) {
- case DateComponents::Date:
- return LocaleWin::currentLocale()->parseDate(input);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return numeric_limits<double>::quiet_NaN();
-}
-
-String formatLocalizedDate(const DateComponents& dateComponents)
-{
- switch (dateComponents.type()) {
- case DateComponents::Date:
- return LocaleWin::currentLocale()->formatDate(dateComponents);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return String();
-}
-
-#if ENABLE(CALENDAR_PICKER)
-String localizedDateFormatText()
-{
- return LocaleWin::currentLocale()->dateFormatText();
-}
-
-const Vector<String>& monthLabels()
-{
- return LocaleWin::currentLocale()->monthLabels();
-}
-
-const Vector<String>& weekDayShortLabels()
-{
- return LocaleWin::currentLocale()->weekDayShortLabels();
-}
-
-unsigned firstDayOfWeek()
-{
- return LocaleWin::currentLocale()->firstDayOfWeek();
-}
-#endif
-
-}
diff --git a/Source/WebCore/platform/text/LocalizedNumber.h b/Source/WebCore/platform/text/LocalizedNumber.h
deleted file mode 100644
index 7a97413e2..000000000
--- a/Source/WebCore/platform/text/LocalizedNumber.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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.
- */
-
-#ifndef LocalizedNumber_h
-#define LocalizedNumber_h
-
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-// Converts the specified number string to another number string
-// localized for the browser's current locale. The input string must
-// conform to HTML floating-point numbers, and is not empty.
-String convertToLocalizedNumber(const String&);
-
-// Converts the specified localized number string to a number string
-// in the HTML floating-point number format. The input string is
-// provided by a end user, and might not be a number string. It's ok
-// that the function returns a string which is not conforms to the
-// HTML floating-point number format, callers of this function are
-// responsible to check the format of the resultant string.
-String convertFromLocalizedNumber(const String&);
-
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-// Returns localized decimal separator, e.g. "." for English, "," for French.
-String localizedDecimalSeparator();
-#endif
-
-} // namespace WebCore
-
-#endif // LocalizedNumber_h
diff --git a/Source/WebCore/platform/text/Localizer.cpp b/Source/WebCore/platform/text/Localizer.cpp
index 8e7725736..9c712b30c 100644
--- a/Source/WebCore/platform/text/Localizer.cpp
+++ b/Source/WebCore/platform/text/Localizer.cpp
@@ -31,10 +31,134 @@
#include "config.h"
#include "Localizer.h"
+#include "DateTimeFormat.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+
+class DateTimeStringBuilder : private DateTimeFormat::TokenHandler {
+ WTF_MAKE_NONCOPYABLE(DateTimeStringBuilder);
+
+public:
+ // The argument objects must be alive until this object dies.
+ DateTimeStringBuilder(Localizer&, const DateComponents&);
+
+ bool build(const String&);
+ String toString();
+
+private:
+ // DateTimeFormat::TokenHandler functions.
+ virtual void visitField(DateTimeFormat::FieldType, int) OVERRIDE FINAL;
+ virtual void visitLiteral(const String&) OVERRIDE FINAL;
+
+ String zeroPadString(const String&, size_t width);
+ void appendNumber(int number, size_t width);
+
+ StringBuilder m_builder;
+ Localizer& m_localizer;
+ const DateComponents& m_date;
+};
+
+DateTimeStringBuilder::DateTimeStringBuilder(Localizer& localizer, const DateComponents& date)
+ : m_localizer(localizer)
+ , m_date(date)
+{
+}
+
+bool DateTimeStringBuilder::build(const String& formatString)
+{
+ m_builder.reserveCapacity(formatString.length());
+ return DateTimeFormat::parse(formatString, *this);
+}
+
+String DateTimeStringBuilder::zeroPadString(const String& string, size_t width)
+{
+ if (string.length() >= width)
+ return string;
+ StringBuilder zeroPaddedStringBuilder;
+ zeroPaddedStringBuilder.reserveCapacity(width);
+ for (size_t i = string.length(); i < width; ++i)
+ zeroPaddedStringBuilder.append("0");
+ zeroPaddedStringBuilder.append(string);
+ return zeroPaddedStringBuilder.toString();
+}
+
+void DateTimeStringBuilder::appendNumber(int number, size_t width)
+{
+ String zeroPaddedNumberString = zeroPadString(String::number(number), width);
+ m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedNumberString));
+}
+
+void DateTimeStringBuilder::visitField(DateTimeFormat::FieldType fieldType, int numberOfPatternCharacters)
+{
+ switch (fieldType) {
+ case DateTimeFormat::FieldTypeYear:
+ // Always use padding width of 4 so it matches DateTimeEditElement.
+ appendNumber(m_date.fullYear(), 4);
+ return;
+ case DateTimeFormat::FieldTypeMonth:
+ // Always use padding width of 2 so it matches DateTimeEditElement.
+ appendNumber(m_date.month() + 1, 2);
+ return;
+ case DateTimeFormat::FieldTypeDayOfMonth:
+ // Always use padding width of 2 so it matches DateTimeEditElement.
+ appendNumber(m_date.monthDay(), 2);
+ return;
+ case DateTimeFormat::FieldTypePeriod:
+ m_builder.append(m_localizer.timeAMPMLabels()[(m_date.hour() >= 12 ? 1 : 0)]);
+ return;
+ case DateTimeFormat::FieldTypeHour12: {
+ int hour12 = m_date.hour() % 12;
+ if (!hour12)
+ hour12 = 12;
+ appendNumber(hour12, numberOfPatternCharacters);
+ return;
+ }
+ case DateTimeFormat::FieldTypeHour23:
+ appendNumber(m_date.hour(), numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeHour11:
+ appendNumber(m_date.hour() % 12, numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeHour24: {
+ int hour24 = m_date.hour();
+ if (!hour24)
+ hour24 = 24;
+ appendNumber(hour24, numberOfPatternCharacters);
+ return;
+ }
+ case DateTimeFormat::FieldTypeMinute:
+ appendNumber(m_date.minute(), numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeSecond:
+ if (!m_date.millisecond())
+ appendNumber(m_date.second(), numberOfPatternCharacters);
+ else {
+ double second = m_date.second() + m_date.millisecond() / 1000.0;
+ String zeroPaddedSecondString = zeroPadString(String::format("%.03f", second), numberOfPatternCharacters + 4);
+ m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedSecondString));
+ }
+ return;
+ default:
+ return;
+ }
+}
+
+void DateTimeStringBuilder::visitLiteral(const String& text)
+{
+ ASSERT(text.length());
+ m_builder.append(text);
+}
+
+String DateTimeStringBuilder::toString()
+{
+ return m_builder.toString();
+}
+
+#endif
+
Localizer::~Localizer()
{
}
@@ -184,7 +308,7 @@ String Localizer::convertFromLocalizedNumber(const String& localized)
return builder.toString();
}
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String Localizer::localizedDecimalSeparator()
{
initializeLocalizerData();
@@ -193,7 +317,7 @@ String Localizer::localizedDecimalSeparator()
String Localizer::timeFormat()
{
- if (!m_localizedTimeFormatText.isEmpty())
+ if (!m_localizedTimeFormatText.isNull())
return m_localizedTimeFormatText;
m_localizedTimeFormatText = "hh:mm:ss";
return m_localizedTimeFormatText;
@@ -201,12 +325,38 @@ String Localizer::timeFormat()
String Localizer::shortTimeFormat()
{
- if (!m_localizedShortTimeFormatText.isEmpty())
+ if (!m_localizedShortTimeFormatText.isNull())
return m_localizedShortTimeFormatText;
m_localizedTimeFormatText = "hh:mm";
return m_localizedShortTimeFormatText;
}
+String Localizer::dateTimeFormatWithSeconds()
+{
+ if (!m_dateTimeFormatWithSeconds.isNull())
+ return m_dateTimeFormatWithSeconds;
+ // FIXME: We should retrieve the separator and the order from the system.
+ StringBuilder builder;
+ builder.append(dateFormat());
+ builder.append(' ');
+ builder.append(timeFormat());
+ m_dateTimeFormatWithSeconds = builder.toString();
+ return m_dateTimeFormatWithSeconds;
+}
+
+String Localizer::dateTimeFormatWithoutSeconds()
+{
+ if (!m_dateTimeFormatWithoutSeconds.isNull())
+ return m_dateTimeFormatWithoutSeconds;
+ // FIXME: We should retrieve the separator and the order from the system.
+ StringBuilder builder;
+ builder.append(dateFormat());
+ builder.append(' ');
+ builder.append(shortTimeFormat());
+ m_dateTimeFormatWithoutSeconds = builder.toString();
+ return m_dateTimeFormatWithoutSeconds;
+}
+
const Vector<String>& Localizer::timeAMPMLabels()
{
if (!m_timeAMPMLabels.isEmpty())
@@ -218,4 +368,22 @@ const Vector<String>& Localizer::timeAMPMLabels()
}
#endif
+String Localizer::formatDateTime(const DateComponents& date, FormatType formatType)
+{
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ if (date.type() != DateComponents::Time && date.type() != DateComponents::Date)
+ return String();
+ DateTimeStringBuilder builder(*this, date);
+ if (date.type() == DateComponents::Time)
+ builder.build(formatType == FormatTypeShort ? shortTimeFormat() : timeFormat());
+ else if (date.type() == DateComponents::Date)
+ builder.build(dateFormat());
+ return builder.toString();
+#else
+ UNUSED_PARAM(date);
+ UNUSED_PARAM(formatType);
+ return String();
+#endif
+}
+
}
diff --git a/Source/WebCore/platform/text/Localizer.h b/Source/WebCore/platform/text/Localizer.h
index e56fc40c9..2ed277c95 100644
--- a/Source/WebCore/platform/text/Localizer.h
+++ b/Source/WebCore/platform/text/Localizer.h
@@ -26,21 +26,45 @@
#ifndef Localizer_h
#define Localizer_h
+#include "DateComponents.h"
+#include "Language.h"
+#include <wtf/PassOwnPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
class Localizer {
+ WTF_MAKE_NONCOPYABLE(Localizer);
+
public:
- static PassOwnPtr<Localizer> create(const AtomicString&);
+ static PassOwnPtr<Localizer> create(const AtomicString& localeIdentifier);
+ static PassOwnPtr<Localizer> createDefault();
+
+ // Converts the specified number string to another number string localized
+ // for this Localizer locale. The input string must conform to HTML
+ // floating-point numbers, and is not empty.
String convertToLocalizedNumber(const String&);
+
+ // Converts the specified localized number string to a number string in the
+ // HTML floating-point number format. The input string is provided by a end
+ // user, and might not be a number string. It's ok that the function returns
+ // a string which is not conforms to the HTML floating-point number format,
+ // callers of this function are responsible to check the format of the
+ // resultant string.
String convertFromLocalizedNumber(const String&);
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ // Returns localized decimal separator, e.g. "." for English, "," for French.
String localizedDecimalSeparator();
+ // Returns date format in Unicode TR35 LDML[1] containing day of month,
+ // month, and year, e.g. "dd/mm/yyyy"
+ // [1] LDML http://unicode.org/reports/tr35/#Date_Format_Patterns
+ virtual String dateFormat() = 0;
+
// Returns time format in Unicode TR35 LDML[1] containing hour, minute, and
// second with optional period(AM/PM), e.g. "h:mm:ss a"
- // [1] LDML http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
+ // [1] LDML http://unicode.org/reports/tr35/#Date_Format_Patterns
virtual String timeFormat();
// Returns time format in Unicode TR35 LDML containing hour, and minute
@@ -48,9 +72,54 @@ public:
// Note: Some platforms return same value as timeFormat().
virtual String shortTimeFormat();
+ // Returns a date-time format in Unicode TR35 LDML. It should have a seconds
+ // field.
+ String dateTimeFormatWithSeconds();
+
+ // Returns a date-time format in Unicode TR35 LDML. It should have no seconds
+ // field.
+ String dateTimeFormatWithoutSeconds();
+
// Returns localized period field(AM/PM) strings.
virtual const Vector<String>& timeAMPMLabels();
#endif
+
+#if ENABLE(CALENDAR_PICKER)
+ // Returns a vector of string of which size is 12. The first item is a
+ // localized string of January, and the last item is a localized string of
+ // December. These strings should not be abbreviations.
+ virtual const Vector<String>& monthLabels() = 0;
+
+ // Returns a vector of string of which size is 7. The first item is a
+ // localized short string of Monday, and the last item is a localized
+ // short string of Saturday. These strings should be short.
+ virtual const Vector<String>& weekDayShortLabels() = 0;
+
+ // The first day of a week. 0 is Sunday, and 6 is Saturday.
+ virtual unsigned firstDayOfWeek() = 0;
+
+ virtual String dateFormatText() = 0;
+
+ // Returns true if people use right-to-left writing in the locale for this
+ // object.
+ virtual bool isRTL() = 0;
+#endif
+
+ // Parses a string representation of a date/time string localized
+ // for this Localizer locale. If the input string is not valid or
+ // an implementation doesn't support localized dates, this
+ // function returns NaN. If the input string is valid this
+ // function returns the number of milliseconds since 1970-01-01
+ // 00:00:00.000 UTC.
+ virtual double parseDateTime(const String&, DateComponents::Type) = 0;
+
+ enum FormatType { FormatTypeUnspecified, FormatTypeShort, FormatTypeMedium };
+
+ // Serializes the specified date into a formatted date string to
+ // display to the user. If an implementation doesn't support
+ // localized dates the function should return an empty string.
+ String formatDateTime(const DateComponents&, FormatType = FormatTypeUnspecified);
+
virtual ~Localizer();
protected:
@@ -61,10 +130,12 @@ protected:
DecimalSymbolsSize
};
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String m_localizedTimeFormatText;
String m_localizedShortTimeFormatText;
Vector<String> m_timeAMPMLabels;
+ String m_dateTimeFormatWithSeconds;
+ String m_dateTimeFormatWithoutSeconds;
#endif
Localizer() : m_hasLocalizerData(false) { }
@@ -83,5 +154,10 @@ private:
bool m_hasLocalizerData;
};
+inline PassOwnPtr<Localizer> Localizer::createDefault()
+{
+ return Localizer::create(defaultLanguage());
+}
+
}
#endif
diff --git a/Source/WebCore/platform/text/TextBreakIterator.cpp b/Source/WebCore/platform/text/TextBreakIterator.cpp
index 1362e8116..edb73ef76 100644
--- a/Source/WebCore/platform/text/TextBreakIterator.cpp
+++ b/Source/WebCore/platform/text/TextBreakIterator.cpp
@@ -49,4 +49,14 @@ unsigned numCharactersInGraphemeClusters(const String& s, unsigned numGraphemeCl
return textBreakCurrent(it);
}
+#if !USE(ICU_UNICODE)
+TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, const AtomicString& locale)
+{
+ Vector<UChar> utf16string(length);
+ for (int i = 0; i < length; ++i)
+ utf16string[i] = string[i];
+ return acquireLineBreakIterator(utf16string.data(), length, locale);
+}
+#endif
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/text/TextBreakIterator.h b/Source/WebCore/platform/text/TextBreakIterator.h
index ac49fb467..de43d0db7 100644
--- a/Source/WebCore/platform/text/TextBreakIterator.h
+++ b/Source/WebCore/platform/text/TextBreakIterator.h
@@ -38,6 +38,7 @@ namespace WebCore {
TextBreakIterator* cursorMovementIterator(const UChar*, int length);
TextBreakIterator* wordBreakIterator(const UChar*, int length);
+ TextBreakIterator* acquireLineBreakIterator(const LChar*, int length, const AtomicString& locale);
TextBreakIterator* acquireLineBreakIterator(const UChar*, int length, const AtomicString& locale);
void releaseLineBreakIterator(TextBreakIterator*);
TextBreakIterator* sentenceBreakIterator(const UChar*, int length);
@@ -56,9 +57,13 @@ namespace WebCore {
class LazyLineBreakIterator {
public:
- LazyLineBreakIterator(const UChar* string = 0, int length = 0, const AtomicString& locale = AtomicString())
+ LazyLineBreakIterator()
+ : m_iterator(0)
+ {
+ }
+
+ LazyLineBreakIterator(String string, const AtomicString& locale = AtomicString())
: m_string(string)
- , m_length(length)
, m_locale(locale)
, m_iterator(0)
{
@@ -70,30 +75,31 @@ public:
releaseLineBreakIterator(m_iterator);
}
- const UChar* string() const { return m_string; }
- int length() const { return m_length; }
+ String string() const { return m_string; }
TextBreakIterator* get()
{
- if (!m_iterator)
- m_iterator = acquireLineBreakIterator(m_string, m_length, m_locale);
+ if (!m_iterator) {
+ if (m_string.is8Bit())
+ m_iterator = acquireLineBreakIterator(m_string.characters8(), m_string.length(), m_locale);
+ else
+ m_iterator = acquireLineBreakIterator(m_string.characters16(), m_string.length(), m_locale);
+ }
return m_iterator;
}
- void reset(const UChar* string, int length, const AtomicString& locale)
+ void reset(String string, const AtomicString& locale)
{
if (m_iterator)
releaseLineBreakIterator(m_iterator);
m_string = string;
- m_length = length;
m_locale = locale;
m_iterator = 0;
}
private:
- const UChar* m_string;
- int m_length;
+ String m_string;
AtomicString m_locale;
TextBreakIterator* m_iterator;
};
diff --git a/Source/WebCore/platform/text/TextBreakIteratorICU.cpp b/Source/WebCore/platform/text/TextBreakIteratorICU.cpp
index 9a80cc2f1..616ba812b 100644
--- a/Source/WebCore/platform/text/TextBreakIteratorICU.cpp
+++ b/Source/WebCore/platform/text/TextBreakIteratorICU.cpp
@@ -54,6 +54,204 @@ static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator
return iterator;
}
+static const int s_UTextCharacterBufferSize = 16;
+
+typedef struct {
+ UText uTextStruct;
+ UChar uCharBuffer[s_UTextCharacterBufferSize + 1];
+} UTextWithBuffer;
+
+static UText emptyUText = UTEXT_INITIALIZER;
+
+static UText* uTextLatin1Clone(UText*, const UText*, UBool, UErrorCode*);
+static int64_t uTextLatin1NativeLength(UText*);
+static UBool uTextLatin1Access(UText*, int64_t, UBool);
+static int32_t uTextLatin1Extract(UText*, int64_t, int64_t, UChar*, int32_t, UErrorCode*);
+static int64_t uTextLatin1MapOffsetToNative(const UText*);
+static int32_t uTextLatin1MapNativeIndexToUTF16(const UText*, int64_t);
+static void uTextLatin1Close(UText*);
+
+static struct UTextFuncs uTextLatin1Funcs = {
+ sizeof(UTextFuncs),
+ 0, 0, 0,
+ uTextLatin1Clone,
+ uTextLatin1NativeLength,
+ uTextLatin1Access,
+ uTextLatin1Extract,
+ 0,
+ 0,
+ uTextLatin1MapOffsetToNative,
+ uTextLatin1MapNativeIndexToUTF16,
+ uTextLatin1Close,
+ 0, 0, 0
+};
+
+static UText* uTextLatin1Clone(UText* destination, const UText* source, UBool deep, UErrorCode* status)
+{
+ ASSERT_UNUSED(deep, !deep);
+
+ if (U_FAILURE(*status))
+ return 0;
+
+ UText* result = utext_setup(destination, sizeof(UChar) * (s_UTextCharacterBufferSize + 1), status);
+ if (U_FAILURE(*status))
+ return destination;
+
+ result->providerProperties = source->providerProperties;
+
+ /* Point at the same position, but with an empty buffer */
+ result->chunkNativeStart = source->chunkNativeStart;
+ result->chunkNativeLimit = source->chunkNativeStart;
+ result->nativeIndexingLimit = static_cast<int32_t>(source->chunkNativeStart);
+ result->chunkOffset = 0;
+ result->context = source->context;
+ result->a = source->a;
+ result->pFuncs = &uTextLatin1Funcs;
+ result->chunkContents = (UChar*)result->pExtra;
+ memset(const_cast<UChar*>(result->chunkContents), 0, sizeof(UChar) * (s_UTextCharacterBufferSize + 1));
+
+ return result;
+}
+
+static int64_t uTextLatin1NativeLength(UText* uText)
+{
+ return uText->a;
+}
+
+static UBool uTextLatin1Access(UText* uText, int64_t index, UBool forward)
+{
+ int64_t length = uText->a;
+
+ if (forward) {
+ if (index < uText->chunkNativeLimit && index >= uText->chunkNativeStart) {
+ /* Already inside the buffer. Set the new offset. */
+ uText->chunkOffset = (int32_t)(index - uText->chunkNativeStart);
+ return TRUE;
+ }
+ if (index >= length && uText->chunkNativeLimit == length) {
+ /* Off the end of the buffer, but we can't get it. */
+ uText->chunkOffset = uText->chunkLength;
+ return FALSE;
+ }
+ } else {
+ if (index <= uText->chunkNativeLimit && index > uText->chunkNativeStart) {
+ /* Already inside the buffer. Set the new offset. */
+ uText->chunkOffset = (int32_t)(index - uText->chunkNativeStart);
+ return TRUE;
+ }
+ if (!index && !uText->chunkNativeStart) {
+ /* Already at the beginning; can't go any farther */
+ uText->chunkOffset = 0;
+ return FALSE;
+ }
+ }
+
+ if (forward) {
+ uText->chunkNativeStart = index;
+ uText->chunkNativeLimit = uText->chunkNativeStart + s_UTextCharacterBufferSize;
+ if (uText->chunkNativeLimit > length)
+ uText->chunkNativeLimit = length;
+
+ uText->chunkOffset = 0;
+ } else {
+ uText->chunkNativeLimit = index;
+ if (uText->chunkNativeLimit > length)
+ uText->chunkNativeLimit = length;
+
+ uText->chunkNativeStart = uText->chunkNativeLimit - s_UTextCharacterBufferSize;
+ if (uText->chunkNativeStart < 0)
+ uText->chunkNativeStart = 0;
+
+ uText->chunkOffset = uText->chunkLength;
+ }
+ uText->chunkLength = (int32_t) (uText->chunkNativeLimit - uText->chunkNativeStart);
+
+ StringImpl::copyChars(const_cast<UChar*>(uText->chunkContents), static_cast<const LChar*>(uText->context) + uText->chunkNativeStart, static_cast<unsigned>(uText->chunkLength));
+
+ uText->nativeIndexingLimit = uText->chunkLength;
+
+ return TRUE;
+}
+
+static int32_t uTextLatin1Extract(UText* uText, int64_t start, int64_t limit, UChar* dest, int32_t destCapacity, UErrorCode* status)
+{
+ int64_t length = uText->a;
+ if (U_FAILURE(*status))
+ return 0;
+
+ if (destCapacity < 0 || (!dest && destCapacity > 0)) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+
+ if (start < 0 || start > limit || (limit - start) > INT32_MAX) {
+ *status = U_INDEX_OUTOFBOUNDS_ERROR;
+ return 0;
+ }
+
+ if (start > length)
+ start = length;
+ if (limit > length)
+ limit = length;
+
+ length = limit - start;
+
+ if (!length)
+ return 0;
+
+ if (destCapacity > 0 && !dest) {
+ int32_t trimmedLength = static_cast<int32_t>(length);
+ if (trimmedLength > destCapacity)
+ trimmedLength = destCapacity;
+
+ StringImpl::copyChars(dest, static_cast<const LChar*>(uText->context) + start, static_cast<unsigned>(trimmedLength));
+ }
+
+ if (length < destCapacity) {
+ dest[length] = 0;
+ if (*status == U_STRING_NOT_TERMINATED_WARNING)
+ *status = U_ZERO_ERROR;
+ } else if (length == destCapacity)
+ *status = U_STRING_NOT_TERMINATED_WARNING;
+ else
+ *status = U_BUFFER_OVERFLOW_ERROR;
+
+ return static_cast<int32_t>(length);
+}
+
+static int64_t uTextLatin1MapOffsetToNative(const UText* uText)
+{
+ return uText->chunkNativeStart + uText->chunkOffset;
+}
+
+static int32_t uTextLatin1MapNativeIndexToUTF16(const UText* uText, int64_t nativeIndex)
+{
+ ASSERT_UNUSED(uText, uText->chunkNativeStart >= nativeIndex);
+ ASSERT_UNUSED(uText, nativeIndex < uText->chunkNativeLimit);
+ return static_cast<int32_t>(nativeIndex);
+}
+
+static void uTextLatin1Close(UText* uText)
+{
+ uText->context = 0;
+}
+
+static UText* UTextOpenLatin1(UTextWithBuffer* uTextLatin1, const LChar* string, unsigned length, UErrorCode* errorCode)
+{
+ UText* result = utext_setup(reinterpret_cast<UText*>(uTextLatin1), sizeof(UChar) * (s_UTextCharacterBufferSize + 1), errorCode);
+
+ if (!U_SUCCESS(*errorCode))
+ return 0;
+
+ result->context = string;
+ result->a = (int64_t)length;
+ result->pFuncs = &uTextLatin1Funcs;
+ result->chunkContents = (UChar*)result->pExtra;
+ memset(const_cast<UChar*>(result->chunkContents), 0, sizeof(UChar) * (s_UTextCharacterBufferSize + 1));
+
+ return result;
+}
+
TextBreakIterator* wordBreakIterator(const UChar* string, int length)
{
static bool createdWordBreakIterator = false;
@@ -62,6 +260,36 @@ TextBreakIterator* wordBreakIterator(const UChar* string, int length)
staticWordBreakIterator, UBRK_WORD, string, length);
}
+TextBreakIterator* acquireLineBreakIterator(const LChar* string, int length, const AtomicString& locale)
+{
+ UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale);
+ if (!iterator)
+ return 0;
+
+ UTextWithBuffer uTextLatin1Local;
+ uTextLatin1Local.uTextStruct = emptyUText;
+ uTextLatin1Local.uTextStruct.extraSize = sizeof(uTextLatin1Local.uCharBuffer);
+ uTextLatin1Local.uTextStruct.pExtra = uTextLatin1Local.uCharBuffer;
+
+ UErrorCode uTextOpenStatus = U_ZERO_ERROR;
+ UText* uTextLatin1 = UTextOpenLatin1(&uTextLatin1Local, string, length, &uTextOpenStatus);
+ if (U_FAILURE(uTextOpenStatus)) {
+ LOG_ERROR("UTextOpenLatin1 failed with status %d", uTextOpenStatus);
+ return 0;
+ }
+
+ UErrorCode setTextStatus = U_ZERO_ERROR;
+ ubrk_setUText(iterator, uTextLatin1, &setTextStatus);
+ if (U_FAILURE(setTextStatus)) {
+ LOG_ERROR("ubrk_setUText failed with status %d", setTextStatus);
+ return 0;
+ }
+
+ utext_close(uTextLatin1);
+
+ return reinterpret_cast<TextBreakIterator*>(iterator);
+}
+
TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length, const AtomicString& locale)
{
UBreakIterator* iterator = LineBreakIteratorPool::sharedPool().take(locale);
diff --git a/Source/WebCore/platform/text/TextEncodingRegistry.cpp b/Source/WebCore/platform/text/TextEncodingRegistry.cpp
index 4140a3872..2790227fa 100644
--- a/Source/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/Source/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -196,8 +196,8 @@ static void pruneBlacklistedCodecs()
TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin();
TextEncodingNameMap::const_iterator end = textEncodingNameMap->end();
for (; it != end; ++it) {
- if (it->second == atomicName)
- names.append(it->first);
+ if (it->value == atomicName)
+ names.append(it->key);
}
size_t length = names.size();
@@ -391,7 +391,7 @@ void dumpTextEncodingNameMap()
TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin();
TextEncodingNameMap::const_iterator end = textEncodingNameMap->end();
for (; it != end; ++it)
- fprintf(stderr, "'%s' => '%s'\n", it->first, it->second);
+ fprintf(stderr, "'%s' => '%s'\n", it->key, it->value);
}
#endif
diff --git a/Source/WebCore/platform/text/blackberry/StringBlackBerry.cpp b/Source/WebCore/platform/text/blackberry/StringBlackBerry.cpp
index 436569f53..ab169b5bf 100644
--- a/Source/WebCore/platform/text/blackberry/StringBlackBerry.cpp
+++ b/Source/WebCore/platform/text/blackberry/StringBlackBerry.cpp
@@ -17,23 +17,27 @@
*/
#include "config.h"
-#include <wtf/text/WTFString.h>
-
-#include "WebString.h"
-using BlackBerry::WebKit::WebString;
+#include "CString.h"
+#include <BlackBerryPlatformString.h>
+#include <wtf/text/WTFString.h>
namespace WTF {
-String::String(const WebString& webString)
- : m_impl(webString.impl())
+String::String(const BlackBerry::Platform::String& webString)
{
+ *this = String::fromUTF8(webString.data(), webString.length());
}
-String::operator WebString() const
+String::operator BlackBerry::Platform::String() const
{
- WebString webString(m_impl.get());
- return webString;
+ if (isEmpty())
+ return BlackBerry::Platform::String::emptyString();
+
+ if (is8Bit())
+ return BlackBerry::Platform::String(reinterpret_cast<const char*>(characters8()), length());
+
+ return BlackBerry::Platform::String(characters(), length());
}
} // namespace WTF
diff --git a/Source/WebCore/platform/text/blackberry/TextBreakIteratorInternalICUBlackBerry.cpp b/Source/WebCore/platform/text/blackberry/TextBreakIteratorInternalICUBlackBerry.cpp
index 04e29470b..009530ed1 100644
--- a/Source/WebCore/platform/text/blackberry/TextBreakIteratorInternalICUBlackBerry.cpp
+++ b/Source/WebCore/platform/text/blackberry/TextBreakIteratorInternalICUBlackBerry.cpp
@@ -19,6 +19,7 @@
#include "config.h"
#include "TextBreakIteratorInternalICU.h"
+#include <BlackBerryPlatformString.h>
#include <LocaleHandler.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/text/mac/LocaleMac.h b/Source/WebCore/platform/text/mac/LocaleMac.h
index 0e48c2e96..ac029ea03 100644
--- a/Source/WebCore/platform/text/mac/LocaleMac.h
+++ b/Source/WebCore/platform/text/mac/LocaleMac.h
@@ -37,6 +37,7 @@
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
+OBJC_CLASS NSCalendar;
OBJC_CLASS NSDateFormatter;
OBJC_CLASS NSLocale;
@@ -48,19 +49,19 @@ class LocaleMac : public Localizer {
public:
static PassOwnPtr<LocaleMac> create(const String&);
static PassOwnPtr<LocaleMac> create(NSLocale*);
- static LocaleMac* currentLocale();
~LocaleMac();
- double parseDate(const String&);
- String formatDate(const DateComponents&);
+ virtual double parseDateTime(const String&, DateComponents::Type) OVERRIDE;
#if ENABLE(CALENDAR_PICKER)
- String dateFormatText();
- const Vector<String>& monthLabels();
- const Vector<String>& weekDayShortLabels();
- unsigned firstDayOfWeek();
+ virtual String dateFormatText() OVERRIDE;
+ virtual const Vector<String>& monthLabels() OVERRIDE;
+ virtual const Vector<String>& weekDayShortLabels() OVERRIDE;
+ virtual unsigned firstDayOfWeek() OVERRIDE;
+ virtual bool isRTL() OVERRIDE;
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ virtual String dateFormat() OVERRIDE;
virtual String timeFormat() OVERRIDE;
virtual String shortTimeFormat() OVERRIDE;
virtual const Vector<String>& timeAMPMLabels() OVERRIDE;
@@ -68,19 +69,21 @@ public:
private:
explicit LocaleMac(NSLocale*);
- NSDateFormatter *createShortDateFormatter();
+ RetainPtr<NSDateFormatter> shortDateFormatter();
virtual void initializeLocalizerData() OVERRIDE;
RetainPtr<NSLocale> m_locale;
+ RetainPtr<NSCalendar> m_gregorianCalendar;
#if ENABLE(CALENDAR_PICKER)
String m_localizedDateFormatText;
Vector<String> m_monthLabels;
Vector<String> m_weekDayShortLabels;
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
- NSDateFormatter *createTimeFormatter();
- NSDateFormatter *createShortTimeFormatter();
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ RetainPtr<NSDateFormatter> timeFormatter();
+ RetainPtr<NSDateFormatter> shortTimeFormatter();
+ String m_dateFormat;
String m_localizedTimeFormatText;
String m_localizedShortTimeFormatText;
Vector<String> m_timeAMPMLabels;
diff --git a/Source/WebCore/platform/text/mac/LocaleMac.mm b/Source/WebCore/platform/text/mac/LocaleMac.mm
index e381c022d..a20254e12 100644
--- a/Source/WebCore/platform/text/mac/LocaleMac.mm
+++ b/Source/WebCore/platform/text/mac/LocaleMac.mm
@@ -34,7 +34,6 @@
#import <Foundation/NSDateFormatter.h>
#import <Foundation/NSLocale.h>
#include "Language.h"
-#include "LocalizedDate.h"
#include "LocalizedStrings.h"
#include <wtf/DateMath.h>
#include <wtf/PassOwnPtr.h>
@@ -71,19 +70,20 @@ PassOwnPtr<Localizer> Localizer::create(const AtomicString& locale)
return LocaleMac::create(determineLocale(locale.string()));
}
-static NSDateFormatter* createDateTimeFormatter(NSLocale* locale, NSDateFormatterStyle dateStyle, NSDateFormatterStyle timeStyle)
+static RetainPtr<NSDateFormatter> createDateTimeFormatter(NSLocale* locale, NSCalendar* calendar, NSDateFormatterStyle dateStyle, NSDateFormatterStyle timeStyle)
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:locale];
[formatter setDateStyle:dateStyle];
[formatter setTimeStyle:timeStyle];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
- [formatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]];
- return formatter;
+ [formatter setCalendar:calendar];
+ return adoptNS(formatter);
}
LocaleMac::LocaleMac(NSLocale* locale)
: m_locale(locale)
+ , m_gregorianCalendar(AdoptNS, [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar])
, m_didInitializeNumberData(false)
{
NSArray* availableLanguages = [NSLocale ISOLanguageCodes];
@@ -91,6 +91,7 @@ LocaleMac::LocaleMac(NSLocale* locale)
NSString* language = [m_locale.get() objectForKey:NSLocaleLanguageCode];
if ([availableLanguages indexOfObject:language] == NSNotFound)
m_locale = [[NSLocale alloc] initWithLocaleIdentifier:defaultLanguage()];
+ [m_gregorianCalendar.get() setLocale:m_locale.get()];
}
LocaleMac::~LocaleMac()
@@ -107,33 +108,21 @@ PassOwnPtr<LocaleMac> LocaleMac::create(NSLocale* locale)
return adoptPtr(new LocaleMac(locale));
}
-LocaleMac* LocaleMac::currentLocale()
+RetainPtr<NSDateFormatter> LocaleMac::shortDateFormatter()
{
- static LocaleMac* currentLocale = new LocaleMac(determineLocale(defaultLanguage()));
- return currentLocale;
+ return createDateTimeFormatter(m_locale.get(), m_gregorianCalendar.get(), NSDateFormatterShortStyle, NSDateFormatterNoStyle);
}
-NSDateFormatter* LocaleMac::createShortDateFormatter()
+double LocaleMac::parseDateTime(const String& input, DateComponents::Type type)
{
- return createDateTimeFormatter(m_locale.get(), NSDateFormatterShortStyle, NSDateFormatterNoStyle);
-}
-
-double LocaleMac::parseDate(const String& input)
-{
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortDateFormatter());
- NSDate *date = [formatter.get() dateFromString:input];
+ if (type != DateComponents::Date)
+ return std::numeric_limits<double>::quiet_NaN();
+ NSDate *date = [shortDateFormatter().get() dateFromString:input];
if (!date)
return std::numeric_limits<double>::quiet_NaN();
return [date timeIntervalSince1970] * msPerSecond;
}
-String LocaleMac::formatDate(const DateComponents& dateComponents)
-{
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortDateFormatter());
- NSTimeInterval interval = dateComponents.millisecondsSinceEpoch() / msPerSecond;
- return String([formatter.get() stringFromDate:[NSDate dateWithTimeIntervalSince1970:interval]]);
-}
-
#if ENABLE(CALENDAR_PICKER)
static bool isYearSymbol(UChar letter) { return letter == 'y' || letter == 'Y' || letter == 'u'; }
static bool isMonthSymbol(UChar letter) { return letter == 'M' || letter == 'L'; }
@@ -184,10 +173,9 @@ static String localizeDateFormat(const String& format)
String LocaleMac::dateFormatText()
{
- if (!m_localizedDateFormatText.isEmpty())
+ if (!m_localizedDateFormatText.isNull())
return m_localizedDateFormatText;
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortDateFormatter());
- m_localizedDateFormatText = localizeDateFormat(String([formatter.get() dateFormat]));
+ m_localizedDateFormatText = localizeDateFormat([shortDateFormatter().get() dateFormat]);
return m_localizedDateFormatText;
}
@@ -196,8 +184,7 @@ const Vector<String>& LocaleMac::monthLabels()
if (!m_monthLabels.isEmpty())
return m_monthLabels;
m_monthLabels.reserveCapacity(12);
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortDateFormatter());
- NSArray *array = [formatter.get() monthSymbols];
+ NSArray *array = [shortDateFormatter().get() monthSymbols];
if ([array count] == 12) {
for (unsigned i = 0; i < 12; ++i)
m_monthLabels.append(String([array objectAtIndex:i]));
@@ -213,8 +200,7 @@ const Vector<String>& LocaleMac::weekDayShortLabels()
if (!m_weekDayShortLabels.isEmpty())
return m_weekDayShortLabels;
m_weekDayShortLabels.reserveCapacity(7);
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortDateFormatter());
- NSArray *array = [formatter.get() shortWeekdaySymbols];
+ NSArray *array = [shortDateFormatter().get() shortWeekdaySymbols];
if ([array count] == 7) {
for (unsigned i = 0; i < 7; ++i)
m_weekDayShortLabels.append(String([array objectAtIndex:i]));
@@ -229,41 +215,50 @@ const Vector<String>& LocaleMac::weekDayShortLabels()
unsigned LocaleMac::firstDayOfWeek()
{
- RetainPtr<NSCalendar> calendar(AdoptNS, [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]);
- [calendar.get() setLocale:m_locale.get()];
// The document for NSCalendar - firstWeekday doesn't have an explanation of
// firstWeekday value. We can guess it by the document of NSDateComponents -
// weekDay, so it can be 1 through 7 and 1 is Sunday.
- return [calendar.get() firstWeekday] - 1;
+ return [m_gregorianCalendar.get() firstWeekday] - 1;
+}
+
+bool LocaleMac::isRTL()
+{
+ return NSLocaleLanguageDirectionRightToLeft == [NSLocale characterDirectionForLanguage:[NSLocale canonicalLanguageIdentifierFromString:[m_locale.get() localeIdentifier]]];
}
#endif
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-NSDateFormatter* LocaleMac::createTimeFormatter()
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+RetainPtr<NSDateFormatter> LocaleMac::timeFormatter()
+{
+ return createDateTimeFormatter(m_locale.get(), m_gregorianCalendar.get(), NSDateFormatterNoStyle, NSDateFormatterMediumStyle);
+}
+
+RetainPtr<NSDateFormatter> LocaleMac::shortTimeFormatter()
{
- return createDateTimeFormatter(m_locale.get(), NSDateFormatterNoStyle, NSDateFormatterMediumStyle);
+ return createDateTimeFormatter(m_locale.get(), m_gregorianCalendar.get(), NSDateFormatterNoStyle, NSDateFormatterShortStyle);
}
-NSDateFormatter* LocaleMac::createShortTimeFormatter()
+String LocaleMac::dateFormat()
{
- return createDateTimeFormatter(m_locale.get(), NSDateFormatterNoStyle, NSDateFormatterShortStyle);
+ if (!m_dateFormat.isNull())
+ return m_dateFormat;
+ m_dateFormat = [shortDateFormatter().get() dateFormat];
+ return m_dateFormat;
}
String LocaleMac::timeFormat()
{
- if (!m_localizedTimeFormatText.isEmpty())
+ if (!m_localizedTimeFormatText.isNull())
return m_localizedTimeFormatText;
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createTimeFormatter());
- m_localizedTimeFormatText = String([formatter.get() dateFormat]);
+ m_localizedTimeFormatText = [timeFormatter().get() dateFormat];
return m_localizedTimeFormatText;
}
String LocaleMac::shortTimeFormat()
{
- if (!m_localizedShortTimeFormatText.isEmpty())
+ if (!m_localizedShortTimeFormatText.isNull())
return m_localizedShortTimeFormatText;
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortTimeFormatter());
- m_localizedShortTimeFormatText = String([formatter.get() dateFormat]);
+ m_localizedShortTimeFormatText = [shortTimeFormatter().get() dateFormat];
return m_localizedShortTimeFormatText;
}
@@ -272,9 +267,9 @@ const Vector<String>& LocaleMac::timeAMPMLabels()
if (!m_timeAMPMLabels.isEmpty())
return m_timeAMPMLabels;
m_timeAMPMLabels.reserveCapacity(2);
- RetainPtr<NSDateFormatter> formatter(AdoptNS, createShortTimeFormatter());
- m_timeAMPMLabels.append(String([formatter.get() AMSymbol]));
- m_timeAMPMLabels.append(String([formatter.get() PMSymbol]));
+ RetainPtr<NSDateFormatter> formatter = shortTimeFormatter();
+ m_timeAMPMLabels.append([formatter.get() AMSymbol]);
+ m_timeAMPMLabels.append([formatter.get() PMSymbol]);
return m_timeAMPMLabels;
}
#endif
@@ -298,9 +293,9 @@ void LocaleMac::initializeLocalizerData()
for (unsigned i = 0; i < 10; ++i)
symbols.append(nineToZero.substring(9 - i, 1));
ASSERT(symbols.size() == DecimalSeparatorIndex);
- symbols.append(String([formatter.get() decimalSeparator]));
+ symbols.append([formatter.get() decimalSeparator]);
ASSERT(symbols.size() == GroupSeparatorIndex);
- symbols.append(String([formatter.get() groupingSeparator]));
+ symbols.append([formatter.get() groupingSeparator]);
ASSERT(symbols.size() == DecimalSymbolsSize);
String positivePrefix([formatter.get() positivePrefix]);
diff --git a/Source/WebCore/platform/text/mac/LocalizedDateMac.cpp b/Source/WebCore/platform/text/mac/LocalizedDateMac.cpp
deleted file mode 100644
index e67c93817..000000000
--- a/Source/WebCore/platform/text/mac/LocalizedDateMac.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * 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 "LocalizedDate.h"
-
-#include "LocaleMac.h"
-#include <limits>
-
-using namespace std;
-
-namespace WebCore {
-
-double parseLocalizedDate(const String& input, DateComponents::Type type)
-{
- switch (type) {
- case DateComponents::Date:
- return LocaleMac::currentLocale()->parseDate(input);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return numeric_limits<double>::quiet_NaN();
-}
-
-String formatLocalizedDate(const DateComponents& dateComponents)
-{
- switch (dateComponents.type()) {
- case DateComponents::Date:
- return LocaleMac::currentLocale()->formatDate(dateComponents);
- case DateComponents::DateTime:
- case DateComponents::DateTimeLocal:
- case DateComponents::Month:
- case DateComponents::Time:
- case DateComponents::Week:
- case DateComponents::Invalid:
- break;
- }
- return String();
-}
-
-#if ENABLE(CALENDAR_PICKER)
-String localizedDateFormatText()
-{
- return LocaleMac::currentLocale()->dateFormatText();
-}
-
-const Vector<String>& monthLabels()
-{
- return LocaleMac::currentLocale()->monthLabels();
-}
-
-const Vector<String>& weekDayShortLabels()
-{
- return LocaleMac::currentLocale()->weekDayShortLabels();
-}
-
-unsigned firstDayOfWeek()
-{
- return LocaleMac::currentLocale()->firstDayOfWeek();
-}
-#endif
-
-}
diff --git a/Source/WebCore/platform/text/qt/TextBoundariesQt.cpp b/Source/WebCore/platform/text/qt/TextBoundariesQt.cpp
index a354ca650..c66d73856 100644
--- a/Source/WebCore/platform/text/qt/TextBoundariesQt.cpp
+++ b/Source/WebCore/platform/text/qt/TextBoundariesQt.cpp
@@ -26,12 +26,12 @@
*/
#include "config.h"
-
#include "TextBoundaries.h"
+
#include "NotImplemented.h"
-#include <QString>
#include <QChar>
+#include <QString>
#include <QDebug>
#include <stdio.h>
diff --git a/Source/WebCore/platform/text/transcoder/FontTranscoder.cpp b/Source/WebCore/platform/text/transcoder/FontTranscoder.cpp
index 4e07f50fb..484228caa 100644
--- a/Source/WebCore/platform/text/transcoder/FontTranscoder.cpp
+++ b/Source/WebCore/platform/text/transcoder/FontTranscoder.cpp
@@ -66,7 +66,7 @@ FontTranscoder::ConverterType FontTranscoder::converterType(const FontDescriptio
if (!fontFamily.isNull()) {
HashMap<AtomicString, ConverterType>::const_iterator found = m_converterTypes.find(fontFamily);
if (found != m_converterTypes.end())
- return found->second;
+ return found->value;
}
// IE's default fonts for Japanese encodings change backslashes into yen signs.
diff --git a/Source/WebCore/platform/text/win/LocalizedNumberWin.cpp b/Source/WebCore/platform/text/win/LocalizedNumberWin.cpp
deleted file mode 100644
index a56071722..000000000
--- a/Source/WebCore/platform/text/win/LocalizedNumberWin.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-#include "config.h"
-#include "LocalizedNumber.h"
-
-#include "LocaleWin.h"
-
-namespace WebCore {
-
-String convertToLocalizedNumber(const String& canonicalNumberString)
-{
- return LocaleWin::currentLocale()->convertToLocalizedNumber(canonicalNumberString);
-}
-
-String convertFromLocalizedNumber(const String& localizedNumberString)
-{
- return LocaleWin::currentLocale()->convertFromLocalizedNumber(localizedNumberString);
-}
-
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
-String localizedDecimalSeparator()
-{
- return LocaleWin::currentLocale()->localizedDecimalSeparator();
-}
-#endif
-} // namespace WebCore
diff --git a/Source/WebCore/platform/text/win/TextCodecWin.cpp b/Source/WebCore/platform/text/win/TextCodecWin.cpp
index e19237d68..879af7697 100644
--- a/Source/WebCore/platform/text/win/TextCodecWin.cpp
+++ b/Source/WebCore/platform/text/win/TextCodecWin.cpp
@@ -105,17 +105,17 @@ LanguageManager::LanguageManager()
i = codePageCharsets().set(cpInfo.uiCodePage, name).iterator;
}
if (i != codePageCharsets().end()) {
- HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(String(i->second.data(), i->second.length()));
+ HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(String(i->value.data(), i->value.length()));
ASSERT(j != knownCharsets().end());
- CharsetInfo& info = j->second;
- info.m_name = i->second.data();
+ CharsetInfo& info = j->value;
+ info.m_name = i->value.data();
info.m_friendlyName = cpInfo.wszDescription;
info.m_aliases.append(name);
info.m_aliases.append(String(cpInfo.wszHeaderCharset).latin1());
info.m_aliases.append(String(cpInfo.wszBodyCharset).latin1());
String cpName = "cp" + String::number(cpInfo.uiCodePage);
info.m_aliases.append(cpName.latin1());
- supportedCharsets().add(i->second.data());
+ supportedCharsets().add(i->value.data());
}
}
}
@@ -126,7 +126,7 @@ static UINT getCodePage(const char* name)
// saying "==" is not found for const_iterator and iterator
const HashMap<String, CharsetInfo>& charsets = knownCharsets();
HashMap<String, CharsetInfo>::const_iterator i = charsets.find(name);
- return i == charsets.end() ? CP_ACP : i->second.m_codePage;
+ return i == charsets.end() ? CP_ACP : i->value.m_codePage;
}
static PassOwnPtr<TextCodec> newTextCodecWin(const TextEncoding& encoding, const void*)
@@ -149,9 +149,9 @@ void TextCodecWin::registerExtendedEncodingNames(EncodingNameRegistrar registrar
for (CharsetSet::iterator i = supportedCharsets().begin(); i != supportedCharsets().end(); ++i) {
HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(*i);
if (j != knownCharsets().end()) {
- registrar(j->second.m_name.data(), j->second.m_name.data());
- for (Vector<CString>::const_iterator alias = j->second.m_aliases.begin(); alias != j->second.m_aliases.end(); ++alias)
- registrar(alias->data(), j->second.m_name.data());
+ registrar(j->value.m_name.data(), j->value.m_name.data());
+ for (Vector<CString>::const_iterator alias = j->value.m_aliases.begin(); alias != j->value.m_aliases.end(); ++alias)
+ registrar(alias->data(), j->value.m_name.data());
}
}
}
@@ -162,7 +162,7 @@ void TextCodecWin::registerExtendedCodecs(TextCodecRegistrar registrar)
for (CharsetSet::iterator i = supportedCharsets().begin(); i != supportedCharsets().end(); ++i) {
HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(*i);
if (j != knownCharsets().end())
- registrar(j->second.m_name.data(), newTextCodecWin, 0);
+ registrar(j->value.m_name.data(), newTextCodecWin, 0);
}
}
@@ -301,7 +301,7 @@ void TextCodecWin::enumerateSupportedEncodings(EncodingReceiver& receiver)
languageManager();
for (CharsetSet::iterator i = supportedCharsets().begin(); i != supportedCharsets().end(); ++i) {
HashMap<String, CharsetInfo>::iterator j = knownCharsets().find(*i);
- if (j != knownCharsets().end() && !receiver.receive(j->second.m_name.data(), j->second.m_friendlyName.charactersWithNullTermination(), j->second.m_codePage))
+ if (j != knownCharsets().end() && !receiver.receive(j->value.m_name.data(), j->value.m_friendlyName.charactersWithNullTermination(), j->value.m_codePage))
break;
}
}
diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index f237444b7..f33550e94 100644
--- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -79,7 +79,7 @@ static bool getDataMapItem(const DragDataMap* dataObject, FORMATETC* format, Str
DragDataMap::const_iterator found = dataObject->find(format->cfFormat);
if (found == dataObject->end())
return false;
- item = found->second[0];
+ item = found->value[0];
return true;
}
@@ -829,7 +829,7 @@ void getClipboardData(IDataObject* dataObject, FORMATETC* format, Vector<String>
ClipboardFormatMap::const_iterator found = formatMap.find(format->cfFormat);
if (found == formatMap.end())
return;
- found->second->getString(dataObject, found->second->format, dataStrings);
+ found->value->getString(dataObject, found->value->format, dataStrings);
}
void setClipboardData(IDataObject* dataObject, UINT format, const Vector<String>& dataStrings)
@@ -838,7 +838,7 @@ void setClipboardData(IDataObject* dataObject, UINT format, const Vector<String>
ClipboardFormatMap::const_iterator found = formatMap.find(format);
if (found == formatMap.end())
return;
- found->second->setString(dataObject, found->second->format, dataStrings);
+ found->value->setString(dataObject, found->value->format, dataStrings);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/win/ClipboardWin.cpp b/Source/WebCore/platform/win/ClipboardWin.cpp
index af5e3a286..ef5bb304d 100644
--- a/Source/WebCore/platform/win/ClipboardWin.cpp
+++ b/Source/WebCore/platform/win/ClipboardWin.cpp
@@ -355,6 +355,8 @@ ClipboardWin::ClipboardWin(ClipboardType clipboardType, const DragDataMap& dataM
ClipboardWin::~ClipboardWin()
{
+ if (m_dragImage)
+ m_dragImage->removeClient(this);
}
static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML)
@@ -482,7 +484,7 @@ bool ClipboardWin::setData(const String& type, const String& data)
return false;
}
-static void addMimeTypesForFormat(HashSet<String>& results, const FORMATETC& format)
+static void addMimeTypesForFormat(ListHashSet<String>& results, const FORMATETC& format)
{
// URL and Text are provided for compatibility with IE's model
if (format.cfFormat == urlFormat()->cfFormat || format.cfFormat == urlWFormat()->cfFormat) {
@@ -497,9 +499,9 @@ static void addMimeTypesForFormat(HashSet<String>& results, const FORMATETC& for
}
// extensions beyond IE's API
-HashSet<String> ClipboardWin::types() const
+ListHashSet<String> ClipboardWin::types() const
{
- HashSet<String> results;
+ ListHashSet<String> results;
if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
return results;
@@ -523,7 +525,7 @@ HashSet<String> ClipboardWin::types() const
} else {
for (DragDataMap::const_iterator it = m_dragDataMap.begin(); it != m_dragDataMap.end(); ++it) {
FORMATETC data;
- data.cfFormat = (*it).first;
+ data.cfFormat = (*it).key;
addMimeTypesForFormat(results, data);
}
}
diff --git a/Source/WebCore/platform/win/ClipboardWin.h b/Source/WebCore/platform/win/ClipboardWin.h
index 8dad415f1..114bd4096 100644
--- a/Source/WebCore/platform/win/ClipboardWin.h
+++ b/Source/WebCore/platform/win/ClipboardWin.h
@@ -64,7 +64,7 @@ public:
bool setData(const String& type, const String& data);
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
void setDragImage(CachedImage*, const IntPoint&);
diff --git a/Source/WebCore/platform/win/FileSystemWin.cpp b/Source/WebCore/platform/win/FileSystemWin.cpp
index 0ab0d7283..54b47efde 100644
--- a/Source/WebCore/platform/win/FileSystemWin.cpp
+++ b/Source/WebCore/platform/win/FileSystemWin.cpp
@@ -238,7 +238,7 @@ static String cachedStorageDirectory(DWORD pathIdentifier)
HashMap<DWORD, String>::iterator it = directories.find(pathIdentifier);
if (it != directories.end())
- return it->second;
+ return it->value;
String directory = storageDirectory(pathIdentifier);
directories.add(pathIdentifier, directory);
diff --git a/Source/WebCore/platform/win/RunLoopWin.cpp b/Source/WebCore/platform/win/RunLoopWin.cpp
index 1663b6613..17d6845e9 100644
--- a/Source/WebCore/platform/win/RunLoopWin.cpp
+++ b/Source/WebCore/platform/win/RunLoopWin.cpp
@@ -126,7 +126,7 @@ void RunLoop::TimerBase::timerFired(RunLoop* runLoop, uint64_t ID)
return;
}
- TimerBase* timer = it->second;
+ TimerBase* timer = it->value;
if (!timer->m_isRepeating) {
runLoop->m_activeTimers.remove(it);
diff --git a/Source/WebCore/platform/win/WCDataObject.cpp b/Source/WebCore/platform/win/WCDataObject.cpp
index c5aaefc7c..4eee4b961 100644
--- a/Source/WebCore/platform/win/WCDataObject.cpp
+++ b/Source/WebCore/platform/win/WCDataObject.cpp
@@ -169,7 +169,7 @@ HRESULT WCDataObject::createInstance(WCDataObject** result, const DragDataMap& d
*result = new WCDataObject;
for (DragDataMap::const_iterator it = dataMap.begin(); it != dataMap.end(); ++it)
- setClipboardData(*result, it->first, it->second);
+ setClipboardData(*result, it->key, it->value);
return S_OK;
}
diff --git a/Source/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp b/Source/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp
index 8a0d3d2b6..e96fb2ba7 100644
--- a/Source/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp
+++ b/Source/WebCore/platform/wince/MIMETypeRegistryWinCE.cpp
@@ -101,8 +101,8 @@ String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type)
initMIMETypeEntensionMap();
for (HashMap<String, String>::iterator i = mimetypeMap.begin(); i != mimetypeMap.end(); ++i) {
- if (equalIgnoringCase(i->second, type))
- return i->first;
+ if (equalIgnoringCase(i->value, type))
+ return i->key;
}
return String();
diff --git a/Source/WebCore/platform/wx/ClipboardWx.cpp b/Source/WebCore/platform/wx/ClipboardWx.cpp
index f6f244fed..dcdb96636 100644
--- a/Source/WebCore/platform/wx/ClipboardWx.cpp
+++ b/Source/WebCore/platform/wx/ClipboardWx.cpp
@@ -71,10 +71,10 @@ bool ClipboardWx::setData(const String& type, const String& data)
}
// extensions beyond IE's API
-HashSet<String> ClipboardWx::types() const
+ListHashSet<String> ClipboardWx::types() const
{
notImplemented();
- HashSet<String> result;
+ ListHashSet<String> result;
return result;
}
diff --git a/Source/WebCore/platform/wx/ClipboardWx.h b/Source/WebCore/platform/wx/ClipboardWx.h
index 9e661d786..37b1fdd8a 100644
--- a/Source/WebCore/platform/wx/ClipboardWx.h
+++ b/Source/WebCore/platform/wx/ClipboardWx.h
@@ -46,7 +46,7 @@ namespace WebCore {
bool setData(const String& type, const String& data);
// extensions beyond IE's API
- virtual HashSet<String> types() const;
+ virtual ListHashSet<String> types() const;
virtual PassRefPtr<FileList> files() const;
IntPoint dragLocation() const;
diff --git a/Source/WebCore/platform/wx/ContextMenuWx.cpp b/Source/WebCore/platform/wx/ContextMenuWx.cpp
index 4189aa952..df2ee527d 100644
--- a/Source/WebCore/platform/wx/ContextMenuWx.cpp
+++ b/Source/WebCore/platform/wx/ContextMenuWx.cpp
@@ -67,8 +67,8 @@ void ContextMenu::appendItem(ContextMenuItem& item)
ItemActionMap::const_iterator end = s_itemActions.end();
for (ItemActionMap::const_iterator it = s_itemActions.begin(); it != end; ++it) {
- if (it->second == itemDescription.action)
- idWx = it->first;
+ if (it->value == itemDescription.action)
+ idWx = it->key;
}
if (itemDescription.subMenu) {
diff --git a/Source/WebCore/platform/wx/wxcode/cairo/non-kerned-drawing.cpp b/Source/WebCore/platform/wx/wxcode/cairo/non-kerned-drawing.cpp
index 406573d13..46ddc6e29 100644
--- a/Source/WebCore/platform/wx/wxcode/cairo/non-kerned-drawing.cpp
+++ b/Source/WebCore/platform/wx/wxcode/cairo/non-kerned-drawing.cpp
@@ -28,12 +28,12 @@
#include "GraphicsContext.h"
#include "SimpleFontData.h"
+#include <vector>
#include <wx/dc.h>
+#include <wx/dcclient.h>
#include <wx/dcgraph.h>
#include <wx/defs.h>
-#include <wx/dcclient.h>
#include <wx/gdicmn.h>
-#include <vector>
#if USE(WXGC)
#include <cairo.h>