From 8995b83bcbfbb68245f779b64e5517627c6cc6ea Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 17 Oct 2012 16:21:14 +0200 Subject: Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592) New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well as the previously cherry-picked changes --- .../platform/graphics/ANGLEWebKitBridge.cpp | 110 +- .../WebCore/platform/graphics/ANGLEWebKitBridge.h | 13 +- Source/WebCore/platform/graphics/BitmapImage.cpp | 13 +- Source/WebCore/platform/graphics/BitmapImage.h | 2 + .../platform/graphics/DisplayRefreshMonitor.cpp | 14 +- .../platform/graphics/DisplayRefreshMonitor.h | 2 +- Source/WebCore/platform/graphics/Extensions3D.h | 16 + Source/WebCore/platform/graphics/FloatSize.h | 2 +- Source/WebCore/platform/graphics/Font.cpp | 48 +- Source/WebCore/platform/graphics/Font.h | 49 +- Source/WebCore/platform/graphics/FontCache.cpp | 79 +- Source/WebCore/platform/graphics/FontCache.h | 18 +- Source/WebCore/platform/graphics/FontData.h | 4 +- .../WebCore/platform/graphics/FontFallbackList.cpp | 18 +- .../WebCore/platform/graphics/FontFallbackList.h | 12 +- Source/WebCore/platform/graphics/FontFastPath.cpp | 125 +-- Source/WebCore/platform/graphics/FontMetrics.h | 12 +- Source/WebCore/platform/graphics/FontSelector.h | 3 +- .../WebCore/platform/graphics/FontWidthVariant.h | 12 +- Source/WebCore/platform/graphics/GlyphBuffer.h | 87 +- .../platform/graphics/GlyphPageTreeNode.cpp | 122 +-- .../WebCore/platform/graphics/GlyphPageTreeNode.h | 39 +- Source/WebCore/platform/graphics/GraphicsContext.h | 2 +- .../WebCore/platform/graphics/GraphicsContext3D.h | 54 +- Source/WebCore/platform/graphics/GraphicsLayer.cpp | 55 +- Source/WebCore/platform/graphics/GraphicsLayer.h | 24 +- .../platform/graphics/GraphicsLayerClient.h | 5 +- .../platform/graphics/GraphicsLayerFactory.h | 49 + Source/WebCore/platform/graphics/Image.h | 6 +- Source/WebCore/platform/graphics/ImageBuffer.cpp | 8 + Source/WebCore/platform/graphics/ImageBuffer.h | 2 + Source/WebCore/platform/graphics/IntPoint.h | 21 - Source/WebCore/platform/graphics/MediaPlayer.cpp | 7 +- Source/WebCore/platform/graphics/MediaPlayer.h | 12 +- .../WebCore/platform/graphics/MediaPlayerPrivate.h | 6 +- Source/WebCore/platform/graphics/NativeImagePtr.h | 9 +- Source/WebCore/platform/graphics/OpenGLESShims.h | 2 +- Source/WebCore/platform/graphics/Path.cpp | 2 +- .../platform/graphics/SegmentedFontData.cpp | 5 +- .../WebCore/platform/graphics/SegmentedFontData.h | 10 +- .../WebCore/platform/graphics/SimpleFontData.cpp | 22 +- Source/WebCore/platform/graphics/SimpleFontData.h | 65 +- Source/WebCore/platform/graphics/TextRun.h | 26 +- Source/WebCore/platform/graphics/TiledBacking.h | 23 +- .../platform/graphics/TiledBackingStore.cpp | 17 +- .../WebCore/platform/graphics/TiledBackingStore.h | 3 + .../WebCore/platform/graphics/WOFFFileFormat.cpp | 25 +- Source/WebCore/platform/graphics/WidthIterator.cpp | 83 +- Source/WebCore/platform/graphics/WidthIterator.h | 21 +- .../MediaPlayerPrivateAVFoundation.cpp | 2 +- .../cf/MediaPlayerPrivateAVFoundationCF.cpp | 4 +- .../objc/MediaPlayerPrivateAVFoundationObjC.h | 30 +- .../objc/MediaPlayerPrivateAVFoundationObjC.mm | 237 +++++ .../blackberry/DisplayRefreshMonitorBlackBerry.cpp | 2 +- .../blackberry/GraphicsContext3DBlackBerry.cpp | 27 +- .../blackberry/GraphicsLayerBlackBerry.cpp | 9 + .../graphics/blackberry/GraphicsLayerBlackBerry.h | 4 +- .../graphics/blackberry/LayerCompositingThread.cpp | 4 +- .../platform/graphics/blackberry/LayerTiler.cpp | 22 +- .../graphics/blackberry/LayerWebKitThread.cpp | 4 +- .../blackberry/MediaPlayerPrivateBlackBerry.cpp | 48 +- .../blackberry/MediaPlayerPrivateBlackBerry.h | 15 +- .../blackberry/TextureCacheCompositingThread.cpp | 6 +- .../graphics/blackberry/VideoLayerWebKitThread.cpp | 4 +- .../platform/graphics/ca/GraphicsLayerCA.cpp | 252 +++-- .../WebCore/platform/graphics/ca/GraphicsLayerCA.h | 14 +- .../WebCore/platform/graphics/ca/PlatformCALayer.h | 3 + .../platform/graphics/ca/PlatformCALayerClient.h | 2 +- .../platform/graphics/ca/mac/PlatformCALayerMac.mm | 8 +- .../WebCore/platform/graphics/ca/mac/TileCache.h | 12 +- .../WebCore/platform/graphics/ca/mac/TileCache.mm | 61 +- .../platform/graphics/ca/mac/WebTileCacheLayer.mm | 13 +- .../platform/graphics/ca/mac/WebTileLayer.mm | 2 +- .../graphics/ca/win/PlatformCALayerWin.cpp | 8 +- .../graphics/ca/win/PlatformCALayerWinInternal.cpp | 6 +- .../platform/graphics/cairo/BitmapImageCairo.cpp | 11 +- .../WebCore/platform/graphics/cairo/FontCairo.cpp | 2 +- .../WebCore/platform/graphics/cairo/GLContext.cpp | 97 +- Source/WebCore/platform/graphics/cairo/GLContext.h | 14 + .../graphics/cairo/GraphicsContext3DCairo.cpp | 51 +- .../graphics/cairo/GraphicsContext3DPrivate.cpp | 10 +- .../graphics/cairo/GraphicsContextCairo.cpp | 2 +- .../graphics/cairo/TransformationMatrixCairo.cpp | 2 +- .../platform/graphics/cg/GraphicsContextCG.cpp | 44 +- .../WebCore/platform/graphics/cg/ImageSourceCG.cpp | 22 +- .../graphics/chromium/Canvas2DLayerBridge.cpp | 32 +- .../graphics/chromium/Canvas2DLayerBridge.h | 5 + .../graphics/chromium/Canvas2DLayerManager.cpp | 27 +- .../graphics/chromium/Canvas2DLayerManager.h | 6 +- .../graphics/chromium/CrossProcessFontLoading.mm | 11 - .../graphics/chromium/Extensions3DChromium.h | 9 + .../graphics/chromium/FontCacheAndroid.cpp | 24 +- .../graphics/chromium/FontCacheChromiumWin.cpp | 38 +- .../graphics/chromium/FontUtilsChromiumWin.cpp | 4 +- .../graphics/chromium/GraphicsLayerChromium.cpp | 13 +- .../graphics/chromium/ImageBufferDataSkia.h | 2 + .../chromium/SimpleFontDataChromiumWin.cpp | 12 +- .../platform/graphics/chromium/VDMXParser.cpp | 3 +- .../graphics/clutter/GraphicsContext3DClutter.cpp | 5 - .../graphics/clutter/GraphicsLayerClutter.cpp | 9 + .../platform/graphics/efl/CairoUtilitiesEfl.cpp | 109 ++ .../platform/graphics/efl/CairoUtilitiesEfl.h | 37 + .../platform/graphics/efl/GraphicsContext3DEfl.cpp | 909 +++------------- .../graphics/efl/GraphicsContext3DPrivate.cpp | 1102 ++------------------ .../graphics/efl/GraphicsContext3DPrivate.h | 204 +--- .../platform/graphics/efl/GraphicsLayerEfl.cpp | 57 - .../platform/graphics/efl/GraphicsLayerEfl.h | 42 - .../WebCore/platform/graphics/egl/GLContextEGL.cpp | 276 +++++ .../WebCore/platform/graphics/egl/GLContextEGL.h | 68 ++ .../graphics/filters/CustomFilterConstants.h | 50 + .../graphics/filters/CustomFilterGlobalContext.cpp | 6 +- .../graphics/filters/CustomFilterMeshGenerator.h | 10 +- .../graphics/filters/CustomFilterProgram.cpp | 9 +- .../graphics/filters/CustomFilterProgram.h | 4 +- .../graphics/filters/CustomFilterProgramInfo.cpp | 18 +- .../graphics/filters/CustomFilterProgramInfo.h | 14 +- .../filters/CustomFilterValidatedProgram.cpp | 21 +- .../platform/graphics/filters/FEConvolveMatrix.cpp | 23 +- .../platform/graphics/filters/FECustomFilter.cpp | 18 +- .../platform/graphics/filters/FECustomFilter.h | 2 - .../platform/graphics/filters/FEGaussianBlur.cpp | 47 +- .../platform/graphics/filters/FELighting.cpp | 13 +- .../platform/graphics/filters/FEMorphology.cpp | 9 +- .../platform/graphics/filters/FETurbulence.cpp | 13 +- .../filters/arm/FECompositeArithmeticNEON.h | 2 - .../graphics/filters/arm/FEGaussianBlurNEON.h | 15 +- .../platform/graphics/filters/arm/FELightingNEON.h | 2 - .../graphics/freetype/FontCacheFreeType.cpp | 6 +- .../graphics/freetype/SimpleFontDataFreeType.cpp | 46 +- .../WebCore/platform/graphics/glx/GLContextGLX.cpp | 98 +- .../WebCore/platform/graphics/glx/GLContextGLX.h | 8 +- .../platform/graphics/gpu/DrawingBuffer.cpp | 5 +- .../WebCore/platform/graphics/gpu/DrawingBuffer.h | 2 +- .../graphics/gstreamer/GRefPtrGStreamer.cpp | 6 + .../platform/graphics/gstreamer/GRefPtrGStreamer.h | 1 + .../graphics/gstreamer/GStreamerVersioning.cpp | 9 +- .../graphics/gstreamer/GStreamerVersioning.h | 3 +- .../platform/graphics/gstreamer/ImageGStreamer.h | 4 - .../graphics/gstreamer/ImageGStreamerQt.cpp | 5 +- .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 8 +- .../graphics/gstreamer/VideoSinkGStreamer.cpp | 14 +- .../harfbuzz/ComplexTextControllerHarfBuzz.cpp | 5 +- .../graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp | 4 - .../platform/graphics/harfbuzz/HarfBuzzSkia.cpp | 12 +- .../graphics/harfbuzz/ng/HarfBuzzNGFace.cpp | 83 +- .../platform/graphics/harfbuzz/ng/HarfBuzzNGFace.h | 9 + .../graphics/harfbuzz/ng/HarfBuzzNGFaceCairo.cpp | 6 +- .../harfbuzz/ng/HarfBuzzNGFaceCoreText.cpp | 9 +- .../graphics/harfbuzz/ng/HarfBuzzNGFaceSkia.cpp | 60 +- .../graphics/harfbuzz/ng/HarfBuzzShaper.cpp | 59 +- .../graphics/mac/ComplexTextController.cpp | 33 +- .../platform/graphics/mac/ComplexTextController.h | 4 +- .../graphics/mac/ComplexTextControllerCoreText.mm | 4 +- .../graphics/mac/DisplayRefreshMonitorMac.cpp | 14 +- .../WebCore/platform/graphics/mac/FontCacheMac.mm | 14 +- .../platform/graphics/mac/FontComplexTextMac.cpp | 11 +- Source/WebCore/platform/graphics/mac/FontMac.mm | 8 +- .../platform/graphics/mac/GraphicsContext3DMac.mm | 6 - .../graphics/mac/MediaPlayerPrivateQTKit.h | 4 + .../graphics/mac/MediaPlayerPrivateQTKit.mm | 17 +- .../graphics/mac/SimpleFontDataCoreText.cpp | 2 +- .../platform/graphics/mac/SimpleFontDataMac.mm | 24 +- Source/WebCore/platform/graphics/mac/WebLayer.mm | 4 +- .../WebCore/platform/graphics/mac/WebTiledLayer.mm | 2 +- .../graphics/opengl/Extensions3DOpenGLCommon.cpp | 59 +- .../graphics/opengl/Extensions3DOpenGLCommon.h | 16 + .../graphics/opengl/GraphicsContext3DOpenGL.cpp | 34 +- .../opengl/GraphicsContext3DOpenGLCommon.cpp | 96 +- .../graphics/opengl/GraphicsContext3DOpenGLES.cpp | 42 +- .../graphics/opentype/OpenTypeVerticalData.cpp | 21 +- .../platform/graphics/openvg/EGLDisplayOpenVG.cpp | 12 +- .../platform/graphics/pango/FontCachePango.cpp | 6 +- .../WebCore/platform/graphics/pango/FontPango.cpp | 2 +- .../graphics/pango/SimpleFontDataPango.cpp | 12 +- .../WebCore/platform/graphics/qt/FontCacheQt.cpp | 8 +- .../platform/graphics/qt/FontCustomPlatformData.h | 2 +- .../platform/graphics/qt/GraphicsContext3DQt.cpp | 34 +- .../platform/graphics/qt/GraphicsContextQt.cpp | 11 +- .../platform/graphics/qt/ImageBufferDataQt.h | 6 +- .../WebCore/platform/graphics/qt/ImageBufferQt.cpp | 151 ++- .../platform/graphics/qt/ImageDecoderQt.cpp | 6 +- .../WebCore/platform/graphics/qt/ImageDecoderQt.h | 6 +- Source/WebCore/platform/graphics/qt/ImageQt.cpp | 90 +- .../platform/graphics/qt/MediaPlayerPrivateQt.cpp | 142 +-- .../platform/graphics/qt/MediaPlayerPrivateQt.h | 21 +- Source/WebCore/platform/graphics/qt/PathQt.cpp | 9 +- Source/WebCore/platform/graphics/qt/PatternQt.cpp | 6 +- .../platform/graphics/qt/SimpleFontDataQt.cpp | 12 +- .../WebCore/platform/graphics/qt/StillImageQt.cpp | 28 +- Source/WebCore/platform/graphics/qt/StillImageQt.h | 16 +- .../graphics/qt/TransformationMatrixQt.cpp | 2 +- .../platform/graphics/qt/TransparencyLayer.h | 14 +- .../platform/graphics/skia/FontCacheSkia.cpp | 12 +- Source/WebCore/platform/graphics/skia/FontSkia.cpp | 15 +- .../platform/graphics/skia/GraphicsContextSkia.cpp | 247 +++-- .../platform/graphics/skia/ImageBufferSkia.cpp | 11 + .../WebCore/platform/graphics/skia/ImageSkia.cpp | 289 +++-- .../graphics/skia/MemoryInstrumentationSkia.cpp | 59 ++ .../graphics/skia/MemoryInstrumentationSkia.h | 44 + .../platform/graphics/skia/NativeImageSkia.cpp | 114 +- .../platform/graphics/skia/NativeImageSkia.h | 58 +- .../platform/graphics/skia/PlatformContextSkia.cpp | 1 + .../platform/graphics/skia/PlatformContextSkia.h | 4 + .../platform/graphics/skia/SimpleFontDataSkia.cpp | 57 +- .../platform/graphics/surfaces/GraphicsSurface.cpp | 4 +- .../platform/graphics/surfaces/GraphicsSurface.h | 12 +- .../graphics/surfaces/GraphicsSurfaceToken.h | 80 ++ .../graphics/surfaces/mac/GraphicsSurfaceMac.cpp | 25 +- .../graphics/surfaces/qt/GraphicsSurfaceGLX.cpp | 18 +- .../graphics/surfaces/qt/GraphicsSurfaceQt.cpp | 3 +- .../graphics/texmap/GraphicsLayerTextureMapper.cpp | 19 +- .../graphics/texmap/GraphicsLayerTextureMapper.h | 4 +- .../platform/graphics/texmap/TextureMapper.h | 5 +- .../graphics/texmap/TextureMapperBackingStore.cpp | 4 +- .../graphics/texmap/TextureMapperBackingStore.h | 5 +- .../platform/graphics/texmap/TextureMapperGL.cpp | 366 +++++-- .../platform/graphics/texmap/TextureMapperGL.h | 18 +- .../graphics/texmap/TextureMapperImageBuffer.cpp | 2 +- .../graphics/texmap/TextureMapperImageBuffer.h | 2 +- .../graphics/texmap/TextureMapperLayer.cpp | 20 +- .../platform/graphics/texmap/TextureMapperLayer.h | 6 +- .../graphics/texmap/TextureMapperPlatformLayer.h | 6 +- .../graphics/texmap/TextureMapperShaderManager.cpp | 939 ++++++----------- .../graphics/texmap/TextureMapperShaderManager.h | 251 ++--- Source/WebCore/platform/graphics/win/FontCGWin.cpp | 8 +- .../WebCore/platform/graphics/win/FontCacheWin.cpp | 32 +- .../MediaPlayerPrivateQuickTimeVisualContext.cpp | 2 +- .../platform/graphics/win/SimpleFontDataWin.cpp | 14 +- .../platform/graphics/wince/FontCacheWinCE.cpp | 20 +- .../platform/graphics/wince/FontPlatformData.cpp | 9 +- .../platform/graphics/wince/FontPlatformData.h | 1 - .../WebCore/platform/graphics/wince/FontWinCE.cpp | 3 +- .../graphics/wince/GraphicsContextWinCE.cpp | 10 +- .../graphics/wince/SimpleFontDataWinCE.cpp | 14 +- .../WebCore/platform/graphics/wx/FontCacheWx.cpp | 18 +- .../platform/graphics/wx/SimpleFontDataWx.cpp | 12 +- 236 files changed, 5061 insertions(+), 4953 deletions(-) create mode 100644 Source/WebCore/platform/graphics/GraphicsLayerFactory.h create mode 100644 Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.cpp create mode 100644 Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h delete mode 100644 Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.cpp delete mode 100644 Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h create mode 100644 Source/WebCore/platform/graphics/egl/GLContextEGL.cpp create mode 100644 Source/WebCore/platform/graphics/egl/GLContextEGL.h create mode 100644 Source/WebCore/platform/graphics/filters/CustomFilterConstants.h create mode 100644 Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.cpp create mode 100644 Source/WebCore/platform/graphics/skia/MemoryInstrumentationSkia.h create mode 100644 Source/WebCore/platform/graphics/surfaces/GraphicsSurfaceToken.h (limited to 'Source/WebCore/platform/graphics') 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& 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 nameBuffer(maxNameLength); + Vector 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& 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 &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 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 &symbols); + bool compileShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, Vector& 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 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) const @@ -143,9 +145,9 @@ void Font::update(PassRefPtr 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* 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*) { 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 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* 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* fallbackFonts = 0, GlyphOverflow* = 0) const; + float floatWidthForSimpleText(const TextRun&, HashSet* 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 m_fontList; + mutable RefPtr 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 @@ -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 > FontVerticalDataCache; +typedef HashMap, WTF::IntHash, WTF::UnsignedWithZeroKeyHashTraits > 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 { } }; -typedef HashMap, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache; +typedef HashMap, 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* gInactiveFontData = 0; +static ListHashSet >* gInactiveFontData = 0; -SimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName, ShouldRetain shouldRetain) +PassRefPtr 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 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; + gInactiveFontData = new ListHashSet >; } FontDataCache::iterator result = gFontDataCache->find(*platformData); if (result == gFontDataCache->end()) { - pair newValue(new SimpleFontData(*platformData), shouldRetain == Retain ? 1 : 0); + pair, 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 fontDataToDelete; - ListHashSet::iterator end = gInactiveFontData->end(); - ListHashSet::iterator it = gInactiveFontData->begin(); + Vector, 20> fontDataToDelete; + ListHashSet >::iterator end = gInactiveFontData->end(); + ListHashSet >::iterator it = gInactiveFontData->begin(); for (int i = 0; i < count && it != end; ++it, ++i) { - const SimpleFontData* fontData = *it.get(); + RefPtr& 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 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(fontData->second.first->verticalData()); + OpenTypeVerticalData* verticalData = const_cast(fontData->value.first->verticalData()); if (verticalData) verticalData->m_inFontCache = true; } Vector 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 FontCache::getFontData(const Font& font, int& familyIndex, FontSelector* fontSelector) { - FontData* result = 0; + RefPtr 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 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* 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 #include +#include +#include #include #include #include @@ -61,11 +63,11 @@ public: enum ShouldRetain { Retain, DoNotRetain }; - const FontData* getFontData(const Font&, int& familyIndex, FontSelector*); + PassRefPtr 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 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&); - SimpleFontData* getCachedFontData(const FontDescription&, const AtomicString&, bool checkingAlternateName = false, ShouldRetain = Retain); - SimpleFontData* getLastResortFallbackFont(const FontDescription&, ShouldRetain = Retain); + PassRefPtr getCachedFontData(const FontDescription&, const AtomicString&, bool checkingAlternateName = false, ShouldRetain = Retain); + PassRefPtr 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 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 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 getSimilarFontPlatformData(const Font&); FontPlatformData* createFontPlatformData(const FontDescription&, const AtomicString& family); - SimpleFontData* getCachedFontData(const FontPlatformData*, ShouldRetain = Retain); + PassRefPtr 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 #include #include +#include +#include #include namespace WebCore { class SimpleFontData; -class FontData { +class FontData : public RefCounted { 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(m_fontList[i].first)); + if (!m_fontList[i]->isCustomFont()) { + ASSERT(!m_fontList[i]->isSegmented()); + fontCache()->releaseFontData(static_cast(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 result = fontCache()->getFontData(*font, m_familyIndex, m_fontSelector.get()); if (result) { - m_fontList.append(pair(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(fontData, fontData->isCustomFont())); + RefPtr 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 { + WTF_MAKE_NONCOPYABLE(FontFallbackList); public: static PassRefPtr 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, 1> m_fontList; + void setGlyphPageZero(GlyphPageTreeNode* pageZero) { m_pageZero = pageZero; } + void setGlyphPages(const GlyphPages& pages) { m_pages = pages; } + + mutable Vector, 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 glyphDataAndPageForCharacterWithTextOrientation(UChar32 character, TextOrientation orientation, GlyphData& data, GlyphPage* page, unsigned pageNumber) { - return glyphDataAndPageForCharacter(c, mirror, variant).first; + if (orientation == TextOrientationVerticalRight) { + RefPtr 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 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 Font::glyphDataAndPageForCharacter(UChar32 c, bool mirror, FontDataVariant variant) const @@ -68,13 +97,13 @@ std::pair 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 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 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 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 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 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 Font::glyphDataAndPageForCharacter(UChar32 c, b codeUnits[1] = U16_TRAIL(c); codeUnitsLength = 2; } - const SimpleFontData* characterFontData = fontCache()->getFontDataForCharacters(*this, codeUnits, codeUnitsLength); + RefPtr 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 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 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* fallbackFonts, GlyphOverflow* glyphOverflow) const +float Font::floatWidthForSimpleText(const TextRun& run, HashSet* 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(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 +#include #include namespace WebCore { @@ -38,7 +39,7 @@ class FontSelectorClient; class FontSelector : public RefCounted { public: virtual ~FontSelector() { } - virtual FontData* getFontData(const FontDescription&, const AtomicString& familyName) = 0; + virtual PassRefPtr 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 m_fontData; Vector m_glyphs; Vector 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::iterator end = roots->end(); for (HashMap::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_iterator end = m_children.end(); - for (HashMap::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::iterator end = roots->end(); for (HashMap::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::iterator end = roots->end(); for (HashMap::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(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 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::iterator end = m_children.end(); - for (HashMap::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::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 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::iterator end = m_children.end(); - for (HashMap::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::iterator end = m_children.end(); - for (HashMap::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::iterator end = WebCore::GlyphPageTreeNode::roots->end(); for (HashMap::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 #include +#include #include #include #include @@ -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* 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* roots; + static GlyphPageTreeNode* pageZeroRoot; + + typedef HashMap > GlyphPageTreeNodeMap; + + GlyphPageTreeNodeMap m_children; GlyphPageTreeNode* m_parent; RefPtr m_page; unsigned m_level : 31; bool m_isSystemFallback : 1; unsigned m_customFontCount; - HashMap m_children; - GlyphPageTreeNode* m_systemFallbackChild; + OwnPtr 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 #include #include @@ -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 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 m_shaderSourceMap; + + typedef HashMap 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 m_extensions; #elif !PLATFORM(CHROMIUM) @@ -1027,7 +1072,6 @@ public: friend class GraphicsContext3DPrivate; OwnPtr 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(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 create(GraphicsLayerFactory*, GraphicsLayerClient*); + + // FIXME: Replace all uses of this create function with the one that takes a GraphicsLayerFactory. static PassOwnPtr 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 GraphicsLayerFactory(GraphicsLayerClient*); - static void setGraphicsLayerFactory(GraphicsLayerFactory); + typedef PassOwnPtr 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 + +namespace WebCore { + +class GraphicsLayer; +class GraphicsLayerClient; + +class GraphicsLayerFactory { +public: + virtual ~GraphicsLayerFactory() { } + + virtual PassOwnPtr 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 +#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 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 -#if PLATFORM(QT) -#include -#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 #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 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 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::const_iterator end = m_ranges.end(); for (Vector::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 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 fontData() const { return m_fontData; } private: UChar32 m_from; UChar32 m_to; - const SimpleFontData* m_fontData; + RefPtr m_fontData; }; class SegmentedFontData : public FontData { public: + static PassRefPtr 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::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::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::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 #include +#include #include +#if PLATFORM(MAC) +#include "WebCoreSystemInterface.h" +#endif + #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) #include #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 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, float fontSize, bool syntheticBold, bool syntheticItalic); + static PassRefPtr create(PassOwnPtr 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 smallCapsFontData(const FontDescription&) const; + PassRefPtr emphasisMarkFontData(const FontDescription&) const; + PassRefPtr brokenIdeographFontData() const; - SimpleFontData* variantFontData(const FontDescription& description, FontDataVariant variant) const + PassRefPtr variantFontData(const FontDescription& description, FontDataVariant variant) const { switch (variant) { case SmallCapsVariant: @@ -112,8 +124,8 @@ public: return const_cast(this); } - SimpleFontData* verticalRightOrientationFontData() const; - SimpleFontData* uprightOrientationFontData() const; + PassRefPtr verticalRightOrientationFontData() const; + PassRefPtr 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(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 , float fontSize, bool syntheticBold, bool syntheticItalic); + void platformInit(); void platformGlyphInit(); void platformCharWidthInit(); @@ -210,7 +244,7 @@ private: void commonInit(); - PassOwnPtr createScaledFontData(const FontDescription&, float scaleFactor) const; + PassRefPtr createScaledFontData(const FontDescription&, float scaleFactor) const; #if (PLATFORM(WIN) && !OS(WINCE)) \ || (OS(WINDOWS) && PLATFORM(WX)) @@ -254,11 +288,11 @@ private: ~DerivedFontData(); bool forCustomFont; - OwnPtr smallCaps; - OwnPtr emphasisMark; - OwnPtr brokenIdeograph; - OwnPtr verticalRightOrientation; - OwnPtr uprightOrientation; + RefPtr smallCaps; + RefPtr emphasisMark; + RefPtr brokenIdeograph; + RefPtr verticalRightOrientation; + RefPtr uprightOrientation; #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) mutable RetainPtr compositeFontReferences; #endif @@ -278,6 +312,9 @@ private: #if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) mutable HashMap > m_CFStringAttributes; +#endif + +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN)) || (PLATFORM(WX) && OS(DARWIN)) || USE(HARFBUZZ_NG) mutable OwnPtr > 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 > 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 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 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 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 -#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 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 using namespace WTF; @@ -43,6 +42,7 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSettypesettingFeatures()) , m_fallbackFonts(fallbackFonts) , m_accountForGlyphBounds(accountForGlyphBounds) , m_maxGlyphBoundingBoxY(numeric_limits::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, 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 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 #include #include @@ -40,8 +42,8 @@ struct WidthIterator { public: WidthIterator(const Font*, const TextRun&, HashSet* 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& 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 inline unsigned advanceInternal(TextIterator&, GlyphBuffer*); + bool shouldApplyFontTransforms() const { return m_run.length() > 1 && (m_typesettingFeatures & (Kerning | Ligatures)); } + + TypesettingFeatures m_typesettingFeatures; HashSet* 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 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 -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 create(MediaPlayer*); static void getSupportedTypes(HashSet& 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 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 m_avAsset; RetainPtr m_avPlayer; RetainPtr m_avPlayerItem; RetainPtr m_videoLayer; @@ -139,6 +159,12 @@ private: RetainPtr m_videoOutput; RetainPtr m_lastImage; #endif + +#if ENABLE(ENCRYPTED_MEDIA) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + RetainPtr m_loaderDelegate; + HashMap > m_keyURIToRequestMap; + HashMap > 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 #import +#import +#import +#import #import #import @@ -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 { + 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 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: + // 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 initDataBuffer = ArrayBuffer::create(4 + keyURISize, 1); + RefPtr initDataView = DataView::create(initDataBuffer, 0, initDataBuffer->byteLength()); + ExceptionCode ec = 0; + initDataView->setUint32(0, keyURISize, true, ec); + + RefPtr 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(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& 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 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 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 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 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 initData = Uint8Array::create(initDataPtr, initDataLength); + String keyURI; + String keyID; + RefPtr certificate; + if (!extractKeyURIKeyIDAndCertificateFromInitData(initData.get(), keyURI, keyID, certificate)) + return MediaPlayer::InvalidPlayerState; + + if (!m_keyURIToRequestMap.contains(keyURI)) + return MediaPlayer::InvalidPlayerState; + + String sessionID = createCanonicalUUIDString(); + + RetainPtr avRequest = m_keyURIToRequestMap.get(keyURI); + + RetainPtr certificateData = adoptNS([[NSData alloc] initWithBytes:certificate->baseAddress() length:certificate->byteLength()]); + NSString* assetStr = keyID; + RetainPtr assetID = [NSData dataWithBytes: [assetStr cStringUsingEncoding:NSUTF8StringEncoding] length:[assetStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; + NSError* error = 0; + RetainPtr 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 keyRequestBuffer = ArrayBuffer::create([keyRequest.get() bytes], [keyRequest.get() length]); + RefPtr 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 avRequest = m_sessionIDToRequestMap.get(sessionID); + RetainPtr 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::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client) +{ + if (!factory) + return adoptPtr(new GraphicsLayerBlackBerry(client)); + + return factory->createGraphicsLayer(client); +} + PassOwnPtr 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 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 #include #include -#include #include #if USE(ACCELERATED_COMPOSITING) @@ -66,15 +66,15 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } -void MediaPlayerPrivate::getSupportedTypes(HashSet& types) +void MediaPlayerPrivate::getSupportedTypes(HashSet& types) { - set supported = PlatformPlayer::allSupportedMimeTypes(); - set::iterator i = supported.begin(); + set supported = PlatformPlayer::allSupportedMimeTypes(); + set::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 create(MediaPlayer*); static void registerMediaEngine(MediaEngineRegistrar); - static void getSupportedTypes(HashSet&); - static MediaPlayer::SupportsType supportsType(const String&, const String&, const KURL&); + static void getSupportedTypes(HashSet&); + 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 m_userDrivenSeekTimer; float m_lastSeekTime; bool m_lastSeekTimePending; + bool m_isAuthenticationChallenging; void waitMetadataTimerFired(Timer*); Timer 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 TextureCacheCompositingThread::textureForTiledContents(const SkBitmap& contents, const IntRect& tileRect, const TileIndex& index, bool isOpaque) { HashMap::iterator it = m_cache.add(key(contents), TextureMap()).iterator; - TextureMap& map = (*it).second; + TextureMap& map = (*it).value; TextureMap::iterator jt = map.add(index, RefPtr()).iterator; - RefPtr texture = (*jt).second; + RefPtr texture = (*jt).value; if (!texture) { texture = createTexture(); #if DEBUG_TEXTURE_MEMORY_USAGE @@ -244,7 +244,7 @@ PassRefPtr 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 @@ -255,6 +257,14 @@ static inline bool supportsAcceleratedFilterAnimations() } #endif +PassOwnPtr GraphicsLayer::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client) +{ + if (!factory) + return adoptPtr(new GraphicsLayerCA(client)); + + return factory->createGraphicsLayer(client); +} + PassOwnPtr 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& propertyAnimations = it->second; + const Vector& 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& 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(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& 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& animations = animationIt->second; + const AnimationProcessingAction& processingInfo = it->value; + const Vector& 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& animations = it->second; + Vector& 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 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 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 // 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 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 m_uncorrectedContentsImage; RetainPtr 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(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(m_delegate.get()) setOwner:nil]; - if (m_layerType == LayerTypeTileCacheLayer) + if (usesTileCacheLayer()) [static_cast(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(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 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 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& tileLayer = m_tiles.add(tileIndex, 0).iterator->second; + RetainPtr& 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 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(_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 >::const_iterator end = m_animations.end(); for (HashMap >::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 >::const_iterator end = layer->animations().end(); for (HashMap >::const_iterator it = layer->animations().begin(); it != end; ++it) { - RetainPtr s(AdoptCF, it->first.createCFString()); - CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->second->platformAnimation()); + RetainPtr s(AdoptCF, it->key.createCFString()); + CACFLayerAddAnimation(layer->platformLayer(), s.get(), it->value->platformAnimation()); } } @@ -328,7 +328,7 @@ PassRefPtr 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 -#if USE(GLX) -#include "GLContextGLX.h" +#if PLATFORM(X11) +#include #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 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::createContextForWindow(uint64_t windowHandle, GLContext* sharingContext) { #if USE(GLX) - return GLContextGLX::createContext(windowHandle, sharingContext); + if (OwnPtr glxContext = GLContextGLX::createContext(windowHandle, sharingContext)) + return glxContext.release(); +#endif +#if USE(EGL) + if (OwnPtr eglContext = GLContextEGL::createContext(windowHandle, sharingContext)) + return eglContext.release(); #endif return nullptr; } GLContext::GLContext() { + addActiveContext(this); } -PassOwnPtr GLContext::createOffscreenContext(GLContext* sharing) +PassOwnPtr GLContext::createOffscreenContext(GLContext* sharingContext) { #if USE(GLX) - return GLContextGLX::createContext(0, sharing); + if (OwnPtr glxContext = GLContextGLX::createContext(0, sharingContext)) + return glxContext.release(); +#endif +#if USE(EGL) + if (OwnPtr 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 #include +#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 #include +#if USE(OPENGL_ES_2) +#include "Extensions3DOpenGLES.h" +#else +#include "Extensions3DOpenGL.h" +#include "OpenGLShims.h" +#endif + namespace WebCore { PassRefPtr GraphicsContext3D::create(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) @@ -55,7 +60,9 @@ PassRefPtr 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& 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 +#if USE(OPENGL_ES_2) +#include +#include +#else +#include "OpenGLShims.h" +#endif + #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) && USE(TEXTURE_MAPPER_GL) #include #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 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 by ensuring that the offsets will get truncated + // to the desired integer. Also see: + 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 by ensuring that the offsets will get truncated - // to the desired integer. Also see: - 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 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 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 m_layer; RefPtr m_context; size_t m_bytesAllocated; + bool m_didRecordDrawCommand; + int m_framesPending; friend class WTF::DoublyLinkedListNode; 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 #include +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 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 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 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 FontCache::getSimilarFontPlatformData(const Font& font) { return 0; } -SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain) +PassRefPtr 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::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 FontCache::fontDataFromDescriptionAndLogFont(const FontDescription& fontDescription, ShouldRetain shouldRetain, const LOGFONT& font, wchar_t* outFontFamilyName) { - SimpleFontData* fontData = getCachedFontData(fontDescription, font.lfFaceName, false, shouldRetain); + RefPtr 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 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 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 FontCache::getSimilarFontPlatformData(const Font& font) { return 0; } -SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain) +PassRefPtr 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 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(&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::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client) +{ + if (!factory) + return adoptPtr(new GraphicsLayerChromium(client)); + + return factory->createGraphicsLayer(client); +} + PassOwnPtr 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 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::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const +PassRefPtr 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::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::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 #include -// For htons/ntohs -#include +#include // 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& 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::create(GraphicsLayerFactory* factory, GraphicsLayerClient* client) +{ + if (!factory) + return adoptPtr(new GraphicsLayerClutter(client)); + + return factory->createGraphicsLayer(client); +} + PassOwnPtr 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 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 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 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(const_cast(ecore_evas_buffer_pixels_get(ee))); + RefPtr 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/CairoUtilitiesEfl.h b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h new file mode 100644 index 000000000..a5cd2e2fb --- /dev/null +++ b/Source/WebCore/platform/graphics/efl/CairoUtilitiesEfl.h @@ -0,0 +1,37 @@ +/* + 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. +*/ + +#ifndef CairoUtilitiesEfl_h +#define CairoUtilitiesEfl_h + +#include +#include +#include +#include +#include + +namespace WebCore { + +PassRefPtr evasObjectFromCairoImageSurface(Evas* canvas, cairo_surface_t*); +PassRefPtr createSurfaceForBackingStore(Ecore_Evas* ee); + +} + +#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 + +#if USE(OPENGL_ES_2) +#include "Extensions3DOpenGLES.h" +#else +#include "Extensions3DOpenGL.h" +#endif namespace WebCore { PassRefPtr GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, RenderStyle renderStyle) { - bool renderDirectlyToEvasGLObject = (renderStyle == RenderDirectlyToHostWindow); - - OwnPtr internal = GraphicsContext3DPrivate::create(attrs, hostWindow, renderDirectlyToEvasGLObject); - if (!internal) - return 0; - RefPtr 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) { notImplemented(); } -PassRefPtr GraphicsContext3D::paintRenderingResultsToImageData(DrawingBuffer* drawingBuffer) +void GraphicsContext3D::setErrorMessageCallback(PassOwnPtr) { 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 imageSurface = adoptRef(cairo_image_surface_create_for_data( + const_cast(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) +#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& 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 +#include #include #include namespace WebCore { -PassOwnPtr GraphicsContext3DPrivate::create(GraphicsContext3D::Attributes attributes, HostWindow* hostWindow, bool renderDirectlyToHostWindow) -{ - OwnPtr 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(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(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) -{ - 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; - } -} - -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(static_cast(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) +void GraphicsContext3DPrivate::setCurrentGLContext(void* context, void* surface) { - 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 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; + m_glContext = context; + m_glSurface = surface; } -bool GraphicsContext3DPrivate::getActiveUniform(Platform3DObject program, GC3Duint index, ActiveInfo& info) +PlatformGraphicsContext3D GraphicsContext3DPrivate::platformGraphicsContext3D() const { - 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 name = adoptArrayPtr(new char[maxNameLength]); - if (!name) { - synthesizeGLError(GL_OUT_OF_MEMORY); - return false; - } + if (m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext) + return m_glContext; - 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; + return m_evasGLContext; } -void GraphicsContext3DPrivate::getAttachedShaders(Platform3DObject program, GC3Dsizei maxCount, GC3Dsizei* count, Platform3DObject* shaders) +bool GraphicsContext3DPrivate::makeContextCurrent() { - makeContextCurrent(); - m_api->glGetAttachedShaders(program, maxCount, count, shaders); + return evas_gl_make_current(m_evasGL, m_evasGLSurface, m_evasGLContext); } -int GraphicsContext3DPrivate::getAttribLocation(Platform3DObject program, const String& name) +#if USE(TEXTURE_MAPPER_GL) +void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask) { - makeContextCurrent(); - return m_api->glGetAttribLocation(program, name.utf8().data()); + notImplemented(); } - -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 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 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 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(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(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(static_cast(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) -{ - makeContextCurrent(); - m_api->glDeleteShader(shader); -} - -void GraphicsContext3DPrivate::deleteTexture(Platform3DObject texture) -{ - makeContextCurrent(); - m_api->glDeleteTextures(1, &texture); -} - -void GraphicsContext3DPrivate::synthesizeGLError(GC3Denum error) -{ - m_syntheticErrors.add(error); -} - -Extensions3D* GraphicsContext3DPrivate::getExtensions() -{ - 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 +#if USE(TEXTURE_MAPPER_GL) +#include +#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 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 m_syntheticErrors; + OwnPtr 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::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/efl/GraphicsLayerEfl.h b/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h deleted file mode 100644 index d03fb1b75..000000000 --- a/Source/WebCore/platform/graphics/efl/GraphicsLayerEfl.h +++ /dev/null @@ -1,42 +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. -*/ - -#ifndef GraphicsLayerEfl_h -#define GraphicsLayerEfl_h - -#if USE(ACCELERATED_COMPOSITING) - -#include "GraphicsLayer.h" - -namespace WebCore { - -class GraphicsLayerEfl : public GraphicsLayer { -public: - GraphicsLayerEfl(GraphicsLayerClient*); - virtual ~GraphicsLayerEfl(); - - virtual void setNeedsDisplay(); - virtual void setNeedsDisplayInRect(const FloatRect&); -}; - -} // namespace WebCore - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // GraphicsLayerEfl_h 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 + +#if USE(OPENGL_ES_2) +#include +#include +#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::createWindowContext(EGLNativeWindowType window, GLContext* sharingContext) +{ + EGLContext eglSharingContext = sharingContext ? static_cast(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::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::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::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(sharingContext)->m_context : 0; + OwnPtr 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 + +namespace WebCore { + +class GLContextEGL : public GLContext { + WTF_MAKE_NONCOPYABLE(GLContextEGL); +public: + enum EGLSurfaceType { PbufferSurface, WindowSurface, PixmapSurface }; + static PassOwnPtr createContext(EGLNativeWindowType, GLContext* sharingContext = 0); + static PassOwnPtr 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 createPbufferContext(EGLContext sharingContext); + static PassOwnPtr 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 CustomFilterGlobalContext::getValidated { CustomFilterValidatedProgramsMap::iterator iter = m_programs.find(programInfo); if (iter != m_programs.end()) - return iter->second; + return iter->value; RefPtr 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 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(&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 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 uniforms; - if (!validator->getUniforms(SH_VERTEX_SHADER, uniforms)) - return; - if (!validator->getUniforms(SH_FRAGMENT_SHADER, uniforms)) - return; - for (Vector::iterator it = uniforms.begin(); it != uniforms.end(); ++it) { + for (Vector::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 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 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 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 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 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 - #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 - #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(srcPixelArray->data()); uint32_t* destinationPixel = reinterpret_cast(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 - #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 FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { RefPtr 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 FontCache::getSimilarFontPlatformData(const Font&) { return 0; } -SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription, ShouldRetain shouldRetain) +PassRefPtr 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 #include #include +#include #include +#include namespace WebCore { @@ -87,17 +89,16 @@ void SimpleFontData::platformDestroy() { } -PassOwnPtr SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const +PassRefPtr 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::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::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); + + WTF::HashMap::AddResult addResult = m_combiningCharacterSequenceSupport->add(String(characters, length), false); + if (!addResult.isNewEntry) + return addResult.iterator->value; + + UErrorCode error = U_ZERO_ERROR; + Vector 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(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 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::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::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::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::createPixmapContext(GLXContext sharingCon PassOwnPtr 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 createPbufferContext(GLXContext sharingContext); static PassOwnPtr 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::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 #include 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* ptr) gst_object_unref(GST_OBJECT(ptr)); } +template <> GRefPtr adoptGRef(GstCaps* ptr) +{ + ASSERT(!ptr || !gstObjectIsFloating(GST_OBJECT(ptr))); + return GRefPtr(ptr, GRefPtrAdopt); +} + template <> GstCaps* refGPtr(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 adoptGRef(GstPadTemplate* ptr); template<> GstPadTemplate* refGPtr(GstPadTemplate* ptr); template<> void derefGPtr(GstPadTemplate* ptr); +template<> GRefPtr adoptGRef(GstCaps* ptr); template<> GstCaps* refGPtr(GstCaps* ptr); template<> void derefGPtr(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 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 #include @@ -28,7 +29,7 @@ class IntSize; }; void webkitGstObjectRefSink(GstObject*); -GstCaps* webkitGstGetPadCaps(GstPad*); +GRefPtr 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 #include -#if PLATFORM(QT) -#include -#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 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 caps = webkitGstGetPadCaps(m_videoSinkPad.get()); if (!caps) return; - RefPtr gstImage = ImageGStreamer::createImage(m_buffer, caps); + RefPtr 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 @@ -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 caps = GST_BUFFER_CAPS(buffer); #else - GstCaps* caps = gst_video_info_to_caps(&priv->info); + GRefPtr 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 FontPlatformData::openTypeTable(uint32_t table) const { RefPtr 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 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 FaceCacheEntry; -typedef HashMap, WTF::UnsignedWithZeroKeyHashTraits > HarfBuzzNGFaceCache; + +class FaceCacheEntry : public RefCounted { +public: + static PassRefPtr 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* glyphCache() { return &m_glyphCache; } + +private: + explicit FaceCacheEntry(hb_face_t* face) + : m_face(face) + { } + + hb_face_t* m_face; + HashMap m_glyphCache; +}; + +typedef HashMap, WTF::IntHash, WTF::UnsignedWithZeroKeyHashTraits > 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 +#include #include #include #include @@ -43,6 +44,9 @@ class FontPlatformData; class HarfBuzzNGFace : public RefCounted { public: + static const hb_tag_t vertTag; + static const hb_tag_t vrt2Tag; + static PassRefPtr 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* 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(userData); - - cairo_scaled_font_t* scaledFont = font->scaledFont(); + cairo_scaled_font_t* scaledFont = reinterpret_cast(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(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(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 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* glyphCacheForFaceCacheEntry) + : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry) + { } + SkPaint m_paint; + WTF::HashMap* 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(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(fontData); + + WTF::HashMap::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(fontData); + HarfBuzzFontData* hbFontData = reinterpret_cast(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(fontData); + HarfBuzzFontData* hbFontData = reinterpret_cast(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(userData); + SkFontID uniqueID = static_cast(reinterpret_cast(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(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(userData); - delete paint; + HarfBuzzFontData* hbFontData = reinterpret_cast(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(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(-1) }; + static hb_feature_t vrt2 = { HarfBuzzNGFace::vrt2Tag, 1, 0, static_cast(-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(-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(-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 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(normalizedLength) == length)) - return 0; - UChar32 normalizedCharacter; - size_t index = 0; - U16_NEXT(&normalizedCharacters[0], index, static_cast(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 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* 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* 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* fallbackFonts) { if (static_cast(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 #include #include +#include #include typedef unsigned short CGGlyph; @@ -53,7 +54,7 @@ public: ComplexTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet* 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* 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 m_stringsFor8BitRuns; Vector 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 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 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; 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 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 = 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(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(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(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(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 { } -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 create(MediaPlayer*); static void getSupportedTypes(HashSet& 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&); 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 #if USE(ACCELERATED_COMPOSITING) -#include "GraphicsLayer.h" +#include "PlatformLayer.h" #endif #if DRAW_FRAME_RATE @@ -190,7 +190,11 @@ PassOwnPtr 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