summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics')
-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.cpp59
-rw-r--r--Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h44
-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
235 files changed, 5036 insertions, 4928 deletions
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/graphics/skia/MemoryInstrumentationSkia.cpp b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp
new file mode 100644
index 000000000..0793c3569
--- /dev/null
+++ b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "MemoryInstrumentationSkia.h"
+
+#include "PlatformMemoryInstrumentation.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkPixelRef.h"
+
+void reportMemoryUsage(const SkBitmap* const& image, WTF::MemoryObjectInfo* memoryObjectInfo)
+{
+ WTF::MemoryClassInfo info(memoryObjectInfo, image);
+ SkPixelRef* pixelRef = image->pixelRef();
+ info.addMember(pixelRef);
+ if (pixelRef)
+ info.addRawBuffer(pixelRef->pixels(), image->getSize());
+}
+
+void reportMemoryUsage(const SkDevice* const& device, WTF::MemoryObjectInfo* memoryObjectInfo)
+{
+ WTF::MemoryClassInfo info(memoryObjectInfo, device);
+ info.addMember(const_cast<SkDevice*>(device)->accessBitmap(false));
+}
+
+void reportMemoryUsage(const SkCanvas* const& canvas, WTF::MemoryObjectInfo* memoryObjectInfo)
+{
+ WTF::MemoryClassInfo info(memoryObjectInfo, canvas);
+ info.addMember(canvas->getDevice());
+}
diff --git a/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h
new file mode 100644
index 000000000..e6f81b0d2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#ifndef MemoryInstrumentationSkia_h
+#define MemoryInstrumentationSkia_h
+
+#include "PlatformMemoryInstrumentation.h"
+
+class SkBitmap;
+class SkDevice;
+class SkCanvas;
+
+void reportMemoryUsage(const SkBitmap* const&, WTF::MemoryObjectInfo*);
+void reportMemoryUsage(const SkDevice* const&, WTF::MemoryObjectInfo*);
+void reportMemoryUsage(const SkCanvas* const&, WTF::MemoryObjectInfo*);
+
+#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