diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-11 10:03:25 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-11 10:03:25 +0100 |
commit | d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (patch) | |
tree | b318cf594dc1da2fa48224005945c9157f35bb41 /Source/WebCore/platform | |
parent | 6300a96eca9f152b379f1bcf3d9efdc5572d989a (diff) | |
download | qtwebkit-d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9.tar.gz |
Imported WebKit commit 75bb2fc5882d2e1b3d5572c2961507996cbca5e3 (http://svn.webkit.org/repository/webkit/trunk@104681)
Diffstat (limited to 'Source/WebCore/platform')
82 files changed, 1407 insertions, 423 deletions
diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp index 9eb1e2fc5..2408cc2b4 100644 --- a/Source/WebCore/platform/KURL.cpp +++ b/Source/WebCore/platform/KURL.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2008, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2007, 2008, 2011, 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 @@ -1050,6 +1050,8 @@ void KURL::parse(const String& string) parse(buffer.data(), &string); } +// FIXME: (lenA != lenB) is never true in the way this function is used. +// FIXME: This is only used for short string, we should replace equal() by a recursive template comparing the strings without loop. static inline bool equal(const char* a, size_t lenA, const char* b, size_t lenB) { if (lenA != lenB) @@ -1104,6 +1106,23 @@ static bool isNonFileHierarchicalScheme(const char* scheme, size_t schemeLength) return false; } +static bool isCanonicalHostnameLowercaseForScheme(const char* scheme, size_t schemeLength) +{ + switch (schemeLength) { + case 2: + return equal("ws", 2, scheme, schemeLength); + case 3: + return equal("ftp", 3, scheme, schemeLength) || equal("wss", 3, scheme, schemeLength); + case 4: + return equal("http", 4, scheme, schemeLength) || equal("file", 4, scheme, schemeLength); + case 5: + return equal("https", 5, scheme, schemeLength); + case 6: + return equal("gopher", 6, scheme, schemeLength); + } + return false; +} + void KURL::parse(const char* url, const String* originalString) { if (!url || url[0] == '\0') { @@ -1344,8 +1363,13 @@ void KURL::parse(const char* url, const String* originalString) if (!(isFile && hostIsLocalHost && !haveNonHostAuthorityPart)) { strPtr = url + hostStart; const char* hostEndPtr = url + hostEnd; - while (strPtr < hostEndPtr) - *p++ = *strPtr++; + if (isCanonicalHostnameLowercaseForScheme(buffer.data(), m_schemeEnd)) { + while (strPtr < hostEndPtr) + *p++ = toASCIILower(*strPtr++); + } else { + while (strPtr < hostEndPtr) + *p++ = *strPtr++; + } } m_hostEnd = p - buffer.data(); diff --git a/Source/WebCore/platform/audio/AudioBus.cpp b/Source/WebCore/platform/audio/AudioBus.cpp index d14305e29..800197e2d 100644 --- a/Source/WebCore/platform/audio/AudioBus.cpp +++ b/Source/WebCore/platform/audio/AudioBus.cpp @@ -244,8 +244,7 @@ void AudioBus::sumFrom(const AudioBus &sourceBus) GAIN_DEZIPPER \ } \ gain = totalDesiredGain; \ - for (; k < framesToProcess; ++k) \ - OP + OP##_V #define STEREO_SUM \ { \ @@ -255,6 +254,11 @@ void AudioBus::sumFrom(const AudioBus &sourceBus) *destinationR++ = sumR; \ } +// FIXME: this can be optimized with additional VectorMath functions. +#define STEREO_SUM_V \ + for (; k < framesToProcess; ++k) \ + STEREO_SUM + // Mono -> stereo (mix equally into L and R) // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center... #define MONO2STEREO_SUM \ @@ -266,12 +270,20 @@ void AudioBus::sumFrom(const AudioBus &sourceBus) *destinationR++ = sumR; \ } +#define MONO2STEREO_SUM_V \ + for (; k < framesToProcess; ++k) \ + MONO2STEREO_SUM + #define MONO_SUM \ { \ float sum = DenormalDisabler::flushDenormalFloatToZero(*destinationL + gain * *sourceL++); \ *destinationL++ = sum; \ } +#define MONO_SUM_V \ + for (; k < framesToProcess; ++k) \ + MONO_SUM + #define STEREO_NO_SUM \ { \ float sampleL = *sourceL++; \ @@ -280,6 +292,12 @@ void AudioBus::sumFrom(const AudioBus &sourceBus) *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleR); \ } +#define STEREO_NO_SUM_V \ + { \ + vsmul(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \ + vsmul(sourceR, 1, &gain, destinationR, 1, framesToProcess - k); \ + } + // Mono -> stereo (mix equally into L and R) // FIXME: Really we should apply an equal-power scaling factor here, since we're effectively panning center... #define MONO2STEREO_NO_SUM \ @@ -289,18 +307,28 @@ void AudioBus::sumFrom(const AudioBus &sourceBus) *destinationR++ = DenormalDisabler::flushDenormalFloatToZero(gain * sample); \ } +#define MONO2STEREO_NO_SUM_V \ + { \ + vsmul(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \ + vsmul(sourceL, 1, &gain, destinationR, 1, framesToProcess - k); \ + } + #define MONO_NO_SUM \ { \ float sampleL = *sourceL++; \ *destinationL++ = DenormalDisabler::flushDenormalFloatToZero(gain * sampleL); \ } +#define MONO_NO_SUM_V \ + { \ + vsmul(sourceL, 1, &gain, destinationL, 1, framesToProcess - k); \ + } + void AudioBus::processWithGainFromMonoStereo(const AudioBus &sourceBus, double* lastMixGain, double targetGain, bool sumToBus) { // We don't want to suddenly change the gain from mixing one time slice to the next, // so we "de-zipper" by slowly changing the gain each sample-frame until we've achieved the target gain. - // FIXME: optimize this method (SSE, etc.) // FIXME: targetGain and lastMixGain should be changed to floats instead of doubles. // Take master bus gain into account as well as the targetGain. @@ -351,8 +379,6 @@ void AudioBus::processWithGainFromMonoStereo(const AudioBus &sourceBus, double* if (this == &sourceBus && *lastMixGain == targetGain && targetGain == 1.0) return; - // FIXME: if (framesToDezipper == 0) and DenormalDisabler::flushDenormalFloatToZero() is a NOP (gcc vs. Visual Studio) - // then we can further optimize the PROCESS_WITH_GAIN codepaths below using vsmul(). if (sourceR && destinationR) { // Stereo PROCESS_WITH_GAIN(STEREO_NO_SUM) diff --git a/Source/WebCore/platform/audio/Reverb.cpp b/Source/WebCore/platform/audio/Reverb.cpp index b6204fff7..2b787ebf3 100644 --- a/Source/WebCore/platform/audio/Reverb.cpp +++ b/Source/WebCore/platform/audio/Reverb.cpp @@ -87,16 +87,23 @@ static double calculateNormalizationScale(AudioBus* response) return scale; } -Reverb::Reverb(AudioBus* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads) +Reverb::Reverb(AudioBus* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize) { - double scale = calculateNormalizationScale(impulseResponse); - if (scale) - impulseResponse->scale(scale); + double scale = 1; + + if (normalize) { + scale = calculateNormalizationScale(impulseResponse); + + if (scale) + impulseResponse->scale(scale); + } initialize(impulseResponse, renderSliceSize, maxFFTSize, numberOfChannels, useBackgroundThreads); - // Undo scaling since this shouldn't be a destructive operation on impulseResponse - if (scale) + // Undo scaling since this shouldn't be a destructive operation on impulseResponse. + // FIXME: What about roundoff? Perhaps consider making a temporary scaled copy + // instead of scaling and unscaling in place. + if (normalize && scale) impulseResponse->scale(1.0 / scale); } diff --git a/Source/WebCore/platform/audio/Reverb.h b/Source/WebCore/platform/audio/Reverb.h index 26f5f8e64..f162e0b70 100644 --- a/Source/WebCore/platform/audio/Reverb.h +++ b/Source/WebCore/platform/audio/Reverb.h @@ -43,7 +43,7 @@ public: enum { MaxFrameSize = 256 }; // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread). - Reverb(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads); + Reverb(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize); void process(AudioBus* sourceBus, AudioBus* destinationBus, size_t framesToProcess); void reset(); diff --git a/Source/WebCore/platform/chromium/PasteboardChromium.cpp b/Source/WebCore/platform/chromium/PasteboardChromium.cpp index f6908de89..26a9f101f 100644 --- a/Source/WebCore/platform/chromium/PasteboardChromium.cpp +++ b/Source/WebCore/platform/chromium/PasteboardChromium.cpp @@ -182,10 +182,12 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP unsigned fragmentEnd = 0; PlatformSupport::clipboardReadHTML(buffer, &markup, &srcURL, &fragmentStart, &fragmentEnd); - RefPtr<DocumentFragment> fragment = - createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, srcURL, FragmentScriptingNotAllowed); - if (fragment) - return fragment.release(); + if (!markup.isEmpty()) { + RefPtr<DocumentFragment> fragment = + createFragmentFromMarkupWithContext(frame->document(), markup, fragmentStart, fragmentEnd, srcURL, FragmentScriptingNotAllowed); + if (fragment) + return fragment.release(); + } } if (allowPlainText) { diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp index 445d1d085..c2d9c58c3 100644 --- a/Source/WebCore/platform/graphics/Font.cpp +++ b/Source/WebCore/platform/graphics/Font.cpp @@ -404,12 +404,22 @@ Font::CodePath Font::codePath(const TextRun& run) const if (supplementaryCharacter <= 0x1F1FF) return Complex; + if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors. + continue; + if (supplementaryCharacter <= 0xE01EF) + return Complex; + // FIXME: Check for Brahmi (U+11000 block), Kaithi (U+11080 block) and other complex scripts // in plane 1 or higher. continue; } + if (c < 0xFE00) // U+FE00 through U+FE0F Unicode variation selectors + continue; + if (c <= 0xFE0F) + return Complex; + if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks continue; if (c <= 0xFE2F) diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h index 11484db61..9a7a86213 100644 --- a/Source/WebCore/platform/graphics/Font.h +++ b/Source/WebCore/platform/graphics/Font.h @@ -116,7 +116,20 @@ public: TypesettingFeatures typesettingFeatures() const { TextRenderingMode textRenderingMode = m_fontDescription.textRenderingMode(); - return textRenderingMode == OptimizeLegibility || textRenderingMode == GeometricPrecision ? Kerning | Ligatures : 0; + TypesettingFeatures features = textRenderingMode == OptimizeLegibility || textRenderingMode == GeometricPrecision ? Kerning | Ligatures : 0; + + switch (m_fontDescription.kerning()) { + case FontDescription::NoneKerning: + features &= ~Kerning; + break; + case FontDescription::NormalKerning: + features |= Kerning; + break; + case FontDescription::AutoKerning: + break; + } + + return features; } FontFamily& firstFamily() { return m_fontDescription.firstFamily(); } diff --git a/Source/WebCore/platform/graphics/FontDescription.h b/Source/WebCore/platform/graphics/FontDescription.h index 71ca2180b..51a257b41 100644 --- a/Source/WebCore/platform/graphics/FontDescription.h +++ b/Source/WebCore/platform/graphics/FontDescription.h @@ -72,6 +72,8 @@ public: enum GenericFamilyType { NoFamily, StandardFamily, SerifFamily, SansSerifFamily, MonospaceFamily, CursiveFamily, FantasyFamily, PictographFamily }; + enum Kerning { AutoKerning, NormalKerning, NoneKerning }; + FontDescription() : m_specifiedSize(0) , m_computedSize(0) @@ -85,6 +87,7 @@ public: , m_genericFamily(NoFamily) , m_usePrinterFont(false) , m_renderingMode(NormalRenderingMode) + , m_kerning(AutoKerning) , m_keywordSize(0) , m_fontSmoothing(AutoSmoothing) , m_textRendering(AutoTextRendering) @@ -112,6 +115,7 @@ public: // only use fixed default size when there is only one font family, and that family is "monospace" bool useFixedDefaultSize() const { return genericFamily() == MonospaceFamily && !family().next() && family().family() == monospaceFamily; } FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); } + Kerning kerning() const { return static_cast<Kerning>(m_kerning); } unsigned keywordSize() const { return m_keywordSize; } FontSmoothingMode fontSmoothing() const { return static_cast<FontSmoothingMode>(m_fontSmoothing); } TextRenderingMode textRenderingMode() const { return static_cast<TextRenderingMode>(m_textRendering); } @@ -141,6 +145,7 @@ public: void setUsePrinterFont(bool p) { m_usePrinterFont = p; } #endif void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; } + void setKerning(Kerning kerning) { m_kerning = kerning; } void setKeywordSize(unsigned s) { m_keywordSize = s; } void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; } void setTextRenderingMode(TextRenderingMode rendering) { m_textRendering = rendering; } @@ -173,6 +178,7 @@ private: bool m_usePrinterFont : 1; unsigned m_renderingMode : 1; // Used to switch between CG and GDI text on Windows. + unsigned m_kerning : 2; // Kerning unsigned m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so, // then we can accurately translate across different generic families to adjust for different preference settings @@ -196,6 +202,7 @@ inline bool FontDescription::operator==(const FontDescription& other) const && m_genericFamily == other.m_genericFamily && m_usePrinterFont == other.m_usePrinterFont && m_renderingMode == other.m_renderingMode + && m_kerning == other.m_kerning && m_keywordSize == other.m_keywordSize && m_fontSmoothing == other.m_fontSmoothing && m_textRendering == other.m_textRendering diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h index 7df134280..13070004c 100644 --- a/Source/WebCore/platform/graphics/ImageBuffer.h +++ b/Source/WebCore/platform/graphics/ImageBuffer.h @@ -59,6 +59,7 @@ namespace WebCore { enum RenderingMode { Unaccelerated, + UnacceleratedNonPlatformBuffer, // Use plain memory allocation rather than platform API to allocate backing store. Accelerated }; diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h index 3d1e7b12c..d14d90879 100644 --- a/Source/WebCore/platform/graphics/Path.h +++ b/Source/WebCore/platform/graphics/Path.h @@ -80,13 +80,16 @@ namespace WebCore { class StrokeStyleApplier; enum PathElementType { - PathElementMoveToPoint, - PathElementAddLineToPoint, - PathElementAddQuadCurveToPoint, - PathElementAddCurveToPoint, - PathElementCloseSubpath + PathElementMoveToPoint, // The points member will contain 1 value. + PathElementAddLineToPoint, // The points member will contain 1 value. + PathElementAddQuadCurveToPoint, // The points member will contain 2 values. + PathElementAddCurveToPoint, // The points member will contain 3 values. + PathElementCloseSubpath // The points member will contain no values. }; + // The points in the sturcture are the same as those that would be used with the + // add... method. For example, a line returns the endpoint, while a cubic returns + // two tangent points and the endpoint. struct PathElement { PathElementType type; FloatPoint* points; diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index de4a56bb8..dd86f004e 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -158,7 +158,6 @@ public: const GlyphData& missingGlyphData() const { return m_missingGlyphData; } void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; } - void updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph&) const; #ifndef NDEBUG virtual String description() const; diff --git a/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp b/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp index 119b3a428..ac0bae306 100644 --- a/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp +++ b/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp @@ -32,21 +32,6 @@ using namespace Unicode; namespace WebCore { -inline static bool isUnicodeBMPVariationSelector(UChar character) -{ - return (0x180B <= character && character <= 0x180D) || (0xFE00 <= character && character <= 0xFE0F); -} - -inline static bool isUnicodeSupplementaryVariationSelector(UChar lead, UChar trail) -{ - // A non-BMP variation selector character is in the range of U+E0100 to U+E01EF. - // It can be a surrogate pair in which the high surrogate is 0xDB40 and - // the low surrogate is in the range of U16_TRAIL(0xE0100 - 0x10000) to U16_TRAIL(0xE01EF - 0x10000). - static const UChar trailStart = U16_TRAIL(0xE0100 - 0x10000); - static const UChar trailEnd = U16_TRAIL(0xE01EF - 0x10000); - return lead == 0xDB40 && trailStart <= trail && trail <= trailEnd; -} - SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, int currentCharacter, int lastCharacter, int endCharacter) : m_characters(characters) , m_currentCharacter(currentCharacter) @@ -98,21 +83,6 @@ bool SurrogatePairAwareTextIterator::consume(UChar32& character, unsigned& clust return true; } -bool SurrogatePairAwareTextIterator::hasTrailingVariationSelector(UChar32& selector, unsigned& clusterLength) -{ - if (static_cast<int>(m_currentCharacter + clusterLength) < m_endCharacter && isUnicodeBMPVariationSelector(m_characters[clusterLength])) { - selector = m_characters[clusterLength]; - clusterLength += 1; - return true; - } - if (static_cast<int>(m_currentCharacter + clusterLength + 1) < m_endCharacter && isUnicodeSupplementaryVariationSelector(m_characters[clusterLength], m_characters[clusterLength + 1])) { - selector = U16_GET_SUPPLEMENTARY(m_characters[clusterLength], m_characters[clusterLength + 1]); - clusterLength += 2; - return true; - } - return false; -} - void SurrogatePairAwareTextIterator::advance(unsigned advanceLength) { m_characters += advanceLength; diff --git a/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h b/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h index 8dcea8d76..1d56eb8b2 100644 --- a/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h +++ b/Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h @@ -32,7 +32,6 @@ public: SurrogatePairAwareTextIterator(const UChar*, int currentCharacter, int lastCharacter, int endCharacter); bool consume(UChar32& character, unsigned& clusterLength); - bool hasTrailingVariationSelector(UChar32& selector, unsigned& clusterLength); void advance(unsigned advanceLength); int currentCharacter() const { return m_currentCharacter; } diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index 06826bef3..d749a4f46 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -115,13 +115,6 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) ASSERT(fontData); - // If a variation selector follows, update glyph with the selector if possible. - UChar32 selector = 0; - if (textIterator.hasTrailingVariationSelector(selector, clusterLength)) { - fontData->updateGlyphWithVariationSelector(character, selector, glyph); - advanceLength = clusterLength; - } - // Now that we have a glyph and font data, get its width. float width; if (character == '\t' && m_run.allowTabs()) { diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index f9e4afb24..e73272ded 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -2181,10 +2181,8 @@ bool GraphicsLayerCA::requiresTiledLayer(float pageScaleFactor) const if (!m_drawsContent || !m_allowTiledLayer || m_layer->layerType() == PlatformCALayer::LayerTypeTileCacheLayer) return false; - float contentsScale = pageScaleFactor * deviceScaleFactor(); - // FIXME: catch zero-size height or width here (or earlier)? - return m_size.width() * contentsScale > cMaxPixelDimension || m_size.height() * contentsScale > cMaxPixelDimension; + return m_size.width() * pageScaleFactor > cMaxPixelDimension || m_size.height() * pageScaleFactor > cMaxPixelDimension; } void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer, float pageScaleFactor, const FloatPoint& positionRelativeToBase) diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm index edf3ffd0d..34c9710d9 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm @@ -29,6 +29,7 @@ #import "PlatformCALayer.h" +#import "AnimationUtilities.h" #import "BlockExceptions.h" #import "FloatConversion.h" #import "GraphicsContext.h" @@ -44,6 +45,9 @@ #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_LEOPARD)) +using std::min; +using std::max; + using namespace WebCore; // This value must be the same as in PlatformCAAnimationMac.mm @@ -746,9 +750,18 @@ void PlatformCALayer::setFilters(const FilterOperations& filters) } case FilterOperation::SEPIA: { const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(filterOperation); - CIFilter* caFilter = [CIFilter filterWithName:@"CISepiaTone"]; + CIFilter* caFilter = [CIFilter filterWithName:@"CIColorMatrix"]; [caFilter setDefaults]; - [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputIntensity"]; + + double t = op->amount(); + t = min(max(0.0, t), 1.0); + + // FIXME: Should put these values into constants (https://bugs.webkit.org/show_bug.cgi?id=76008) + [caFilter setValue:[CIVector vectorWithX:WebCore::blend(1.0, 0.393, t) Y:WebCore::blend(0.0, 0.769, t) Z:WebCore::blend(0.0, 0.189, t) W:0] forKey:@"inputRVector"]; + [caFilter setValue:[CIVector vectorWithX:WebCore::blend(0.0, 0.349, t) Y:WebCore::blend(1.0, 0.686, t) Z:WebCore::blend(0.0, 0.168, t) W:0] forKey:@"inputGVector"]; + [caFilter setValue:[CIVector vectorWithX:WebCore::blend(0.0, 0.272, t) Y:WebCore::blend(0.0, 0.534, t) Z:WebCore::blend(1.0, 0.131, t) W:0] forKey:@"inputBVector"]; + [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:1] forKey:@"inputAVector"]; + [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:0] forKey:@"inputBiasVector"]; [caFilter setName:@"sepiaFilter"]; [array.get() addObject:caFilter]; break; diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index ee87f5327..20ffba646 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -527,8 +527,9 @@ void GraphicsContext::clipConvexPolygon(size_t numberOfPoints, const FloatPoint* void GraphicsContext::applyStrokePattern() { CGContextRef cgContext = platformContext(); + AffineTransform userToBaseCTM = AffineTransform(wkGetUserToBaseCTM(cgContext)); - RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_state.strokePattern->createPlatformPattern(getCTM())); + RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_state.strokePattern->createPlatformPattern(userToBaseCTM)); if (!platformPattern) return; @@ -542,8 +543,9 @@ void GraphicsContext::applyStrokePattern() void GraphicsContext::applyFillPattern() { CGContextRef cgContext = platformContext(); + AffineTransform userToBaseCTM = AffineTransform(wkGetUserToBaseCTM(cgContext)); - RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_state.fillPattern->createPlatformPattern(getCTM())); + RetainPtr<CGPatternRef> platformPattern(AdoptCF, m_state.fillPattern->createPlatformPattern(userToBaseCTM)); if (!platformPattern) return; @@ -1253,8 +1255,7 @@ AffineTransform GraphicsContext::getCTM() const if (paintingDisabled()) return AffineTransform(); - CGAffineTransform t = CGContextGetCTM(platformContext()); - return AffineTransform(t.a, t.b, t.c, t.d, t.tx, t.ty); + return AffineTransform(CGContextGetCTM(platformContext())); } FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode roundingMode) diff --git a/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp b/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp index b49a2ab38..dd60cfca0 100644 --- a/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp +++ b/Source/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp @@ -54,6 +54,11 @@ TransformationMatrix::operator CGAffineTransform() const narrowPrecisionToCGFloat(f())); } +AffineTransform::AffineTransform(const CGAffineTransform& t) +{ + setMatrix(t.a, t.b, t.c, t.d, t.tx, t.ty); +} + AffineTransform::operator CGAffineTransform() const { return CGAffineTransformMake(narrowPrecisionToCGFloat(a()), diff --git a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h index fa64818ad..153dd2c3c 100644 --- a/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h +++ b/Source/WebCore/platform/graphics/chromium/BitmapCanvasLayerTextureUpdater.h @@ -37,7 +37,9 @@ namespace WebCore { class LayerPainterChromium; -// A CanvasLayerTextureUpdater with an internal bitmap. +// This class rasterizes the contentRect into a PlatformCanvas. It then updates +// textures by copying from the canvas into the texture, using MapSubImage if +// possible. class BitmapCanvasLayerTextureUpdater : public CanvasLayerTextureUpdater { public: class Texture : public LayerTextureUpdater::Texture { diff --git a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h index e5163c202..6f2f10d9b 100644 --- a/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h +++ b/Source/WebCore/platform/graphics/chromium/BitmapSkPictureCanvasLayerTextureUpdater.h @@ -36,6 +36,8 @@ namespace WebCore { +// This class records the contentRect into an SkPicture, then software rasterizes +// the SkPicture into bitmaps for each tile. This implements CCSettings::perTilePainting. class BitmapSkPictureCanvasLayerTextureUpdater : public SkPictureCanvasLayerTextureUpdater { public: class Texture : public CanvasLayerTextureUpdater::Texture { diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerTextureUpdater.h index a8feff342..4415f6986 100644 --- a/Source/WebCore/platform/graphics/chromium/CanvasLayerTextureUpdater.h +++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerTextureUpdater.h @@ -36,7 +36,9 @@ namespace WebCore { class GraphicsContext3D; class LayerPainterChromium; -// A LayerTextureUpdater with an internal canvas. +// Base class for BitmapCanvasLayerTextureUpdater and +// SkPictureCanvasLayerTextureUpdater that reduces code duplication between +// their respective paintContents implementations. class CanvasLayerTextureUpdater : public LayerTextureUpdater { public: virtual ~CanvasLayerTextureUpdater(); diff --git a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h index 1b1d11bfa..4a10c858e 100644 --- a/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h +++ b/Source/WebCore/platform/graphics/chromium/FrameBufferSkPictureCanvasLayerTextureUpdater.h @@ -34,6 +34,9 @@ namespace WebCore { +// This class records the contentRect into an SkPicture, then uses accelerated +// drawing to update the texture. The accelerated drawing goes to an +// intermediate framebuffer and then is copied to the destination texture once done. class FrameBufferSkPictureCanvasLayerTextureUpdater : public SkPictureCanvasLayerTextureUpdater { public: class Texture : public LayerTextureUpdater::Texture { diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp index 1d6294964..a0fb35f02 100644 --- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp @@ -189,7 +189,9 @@ bool ImageLayerChromium::drawsContent() const void ImageLayerChromium::createTextureUpdater(const CCLayerTreeHost* host) { - m_textureUpdater = ImageLayerTextureUpdater::create(host->layerRendererCapabilities().usingMapSub); + // Avoid creating a new texture updater which would not have a valid copy of the current image. + if (!m_textureUpdater) + m_textureUpdater = ImageLayerTextureUpdater::create(host->layerRendererCapabilities().usingMapSub); } bool ImageLayerChromium::needsContentsScale() const diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index daeb97f9a..933e78253 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -435,13 +435,14 @@ void LayerRendererChromium::drawDebugBorderQuad(const CCDebugBorderDrawQuad* qua ASSERT(program && program->initialized()); GLC(context(), context()->useProgram(program->program())); - TransformationMatrix renderMatrix = quad->layerTransform(); const IntRect& layerRect = quad->quadRect(); + TransformationMatrix renderMatrix = quad->quadTransform(); + renderMatrix.translate(0.5 * layerRect.width() + layerRect.x(), 0.5 * layerRect.height() + layerRect.y()); renderMatrix.scaleNonUniform(layerRect.width(), layerRect.height()); LayerRendererChromium::toGLMatrix(&glMatrix[0], projectionMatrix() * renderMatrix); GLC(context(), context()->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1)); - GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), quad->color().red() / 255.0, quad->color().green() / 255.0, quad->color().blue() / 255.0, 1)); + GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), quad->color().red() / 255.0, quad->color().green() / 255.0, quad->color().blue() / 255.0, quad->color().alpha() / 255.0)); GLC(context(), context()->lineWidth(quad->width())); @@ -679,11 +680,9 @@ void LayerRendererChromium::finishDrawingFrame() size_t contentsMemoryUseBytes = m_contentsTextureAllocator->currentMemoryUseBytes(); size_t reclaimLimit = TextureManager::reclaimLimitBytes(viewportSize()); - if (reclaimLimit > contentsMemoryUseBytes) - m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(reclaimLimit - contentsMemoryUseBytes); - else - m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(0); - + size_t preferredLimit = reclaimLimit > contentsMemoryUseBytes ? reclaimLimit - contentsMemoryUseBytes : 0; + m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(preferredLimit); + m_renderSurfaceTextureManager->reduceMemoryToLimit(preferredLimit); m_renderSurfaceTextureManager->deleteEvictedTextures(m_renderSurfaceTextureAllocator.get()); if (settings().compositeOffscreen) diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index 93e8d86c6..4e1822b31 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -96,6 +96,11 @@ private: TransformationMatrix m_originTransform; IntRect m_clipRect; Vector<RefPtr<LayerChromium> > m_layerList; + + // For CCLayerIteratorActions + int m_targetRenderSurfaceLayerIndexHistory; + int m_currentLayerIndexHistory; + friend struct CCLayerIteratorActions; }; } diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp index 9681746ba..78ad56af9 100644 --- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp +++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp @@ -199,9 +199,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const return static_cast<float>(width); } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/SkPictureCanvasLayerTextureUpdater.h b/Source/WebCore/platform/graphics/chromium/SkPictureCanvasLayerTextureUpdater.h index 440f8b03e..95b78c3b9 100644 --- a/Source/WebCore/platform/graphics/chromium/SkPictureCanvasLayerTextureUpdater.h +++ b/Source/WebCore/platform/graphics/chromium/SkPictureCanvasLayerTextureUpdater.h @@ -39,6 +39,11 @@ namespace WebCore { class LayerPainterChromium; +// This class records the contentRect into an SkPicture. Subclasses, provide +// different implementations of tile updating based on this recorded picture. +// The BitmapSkPictureCanvasLayerTextureUpdater and +// FrameBufferSkPictureCanvasLayerTextureUpdater are two examples of such +// implementations. class SkPictureCanvasLayerTextureUpdater : public CanvasLayerTextureUpdater { public: virtual ~SkPictureCanvasLayerTextureUpdater(); diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp index 30207be38..516cea90a 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp @@ -112,7 +112,6 @@ void TextureManager::setMaxMemoryLimitBytes(size_t memoryLimitBytes) void TextureManager::setPreferredMemoryLimitBytes(size_t memoryLimitBytes) { - reduceMemoryToLimit(memoryLimitBytes); m_preferredMemoryLimitBytes = memoryLimitBytes; } diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.h b/Source/WebCore/platform/graphics/chromium/TextureManager.h index c6c21ad59..a66e9d536 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.h +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.h @@ -64,7 +64,9 @@ public: static size_t memoryUseBytes(const IntSize&, GC3Denum format); void setMaxMemoryLimitBytes(size_t); + size_t maxMemoryLimitBytes() { return m_maxMemoryLimitBytes; } void setPreferredMemoryLimitBytes(size_t); + size_t preferredMemoryLimitBytes() { return m_preferredMemoryLimitBytes; } TextureToken getToken(); void releaseToken(TextureToken); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDebugBorderDrawQuad.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCDebugBorderDrawQuad.cpp index 4056a4284..b4a71dc5f 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCDebugBorderDrawQuad.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCDebugBorderDrawQuad.cpp @@ -40,7 +40,7 @@ CCDebugBorderDrawQuad::CCDebugBorderDrawQuad(const CCSharedQuadState* sharedQuad , m_width(width) { m_quadOpaque = false; - if (m_color.alpha() != 1) + if (m_color.hasAlpha()) m_needsBlending = true; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.cpp index 35477065e..e7b19a760 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.cpp @@ -40,10 +40,11 @@ PassRefPtr<CCDelayBasedTimeSource> CCDelayBasedTimeSource::create(double interva CCDelayBasedTimeSource::CCDelayBasedTimeSource(double intervalMs, CCThread* thread) : m_client(0) + , m_hasTickTarget(false) , m_intervalMs(intervalMs) , m_tickTarget(0) , m_state(STATE_INACTIVE) - , m_thread(thread) + , m_timer(thread, this) { } @@ -51,29 +52,45 @@ void CCDelayBasedTimeSource::setActive(bool active) { if (!active) { m_state = STATE_INACTIVE; + m_timer.stop(); return; } - // Becoming active is deferred: we post a 0-delay task. When it runs, we use - // that to establish the timebase, become truly active, and fire the first - // tick. if (m_state == STATE_STARTING || m_state == STATE_ACTIVE) return; - m_state = STATE_STARTING; - postTickTask(0); -} + if (!m_hasTickTarget) { + // Becoming active the first time is deferred: we post a 0-delay task. When + // it runs, we use that to establish the timebase, become truly active, and + // fire the first tick. + m_state = STATE_STARTING; + m_timer.startOneShot(0); + return; + } -void CCDelayBasedTimeSource::postTickTask(long long delay) -{ - this->ref(); - m_thread->postDelayedTask(createCCThreadTask(this, &CCDelayBasedTimeSource::onTick), delay); + m_state = STATE_ACTIVE; + + double nowMs = monotonicallyIncreasingTimeMs(); + postNextTickTask(nowMs); } -void CCDelayBasedTimeSource::onTick() +void CCDelayBasedTimeSource::onTimerFired() { - updateState(); - this->deref(); + ASSERT(m_state != STATE_INACTIVE); + + double nowMs = monotonicallyIncreasingTimeMs(); + + if (m_state == STATE_STARTING) { + m_hasTickTarget = true; + m_tickTarget = nowMs; + m_state = STATE_ACTIVE; + } + + postNextTickTask(nowMs); + + // Fire the tick + if (m_client) + m_client->onTimerTick(); } double CCDelayBasedTimeSource::monotonicallyIncreasingTimeMs() const @@ -124,36 +141,22 @@ double CCDelayBasedTimeSource::monotonicallyIncreasingTimeMs() const // // For the really late delay, we we move to the next logical tick. The timebase is not reset. // now=37 tickTarget=16.667 newTarget=50.000 --> tick(), postDelayedTask(floor(50.000-37)) --> postDelayedTask(13) -void CCDelayBasedTimeSource::updateState() +void CCDelayBasedTimeSource::postNextTickTask(double nowMs) { - if (m_state == STATE_INACTIVE) - return; - - double now = monotonicallyIncreasingTimeMs(); - - if (m_state == STATE_STARTING) { - m_tickTarget = now; - m_state = STATE_ACTIVE; - } - - int numIntervalsElapsed = static_cast<int>(floor((now - m_tickTarget) / m_intervalMs)); + int numIntervalsElapsed = static_cast<int>(floor((nowMs - m_tickTarget) / m_intervalMs)); double lastEffectiveTick = m_tickTarget + m_intervalMs * numIntervalsElapsed; double newTickTarget = lastEffectiveTick + m_intervalMs; - long long delay = static_cast<long long>(newTickTarget - now); + long long delay = static_cast<long long>(newTickTarget - nowMs); if (!delay) { newTickTarget = newTickTarget + m_intervalMs; - delay = static_cast<long long>(newTickTarget - now); + delay = static_cast<long long>(newTickTarget - nowMs); } // Post another task *before* the tick and update state - ASSERT(newTickTarget > now); - postTickTask(delay); + ASSERT(newTickTarget > nowMs); + m_timer.startOneShot(delay); m_tickTarget = newTickTarget; - - // Fire the tick - if (m_client) - m_client->onTimerTick(); } } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.h b/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.h index 6cc7338d5..6336b8849 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCDelayBasedTimeSource.h @@ -26,6 +26,7 @@ #define CCDelayBasedTimeSource_h #include "cc/CCTimeSource.h" +#include "cc/CCTimer.h" #include <wtf/PassRefPtr.h> @@ -35,7 +36,7 @@ class CCThread; // This timer implements a time source that achieves the specified interval // in face of millisecond-precision delayed callbacks and random queueing delays. -class CCDelayBasedTimeSource : public CCTimeSource { +class CCDelayBasedTimeSource : public CCTimeSource, CCTimerClient { public: static PassRefPtr<CCDelayBasedTimeSource> create(double intervalMs, CCThread*); @@ -45,14 +46,15 @@ public: virtual void setActive(bool); + // CCTimerClient implementation. + virtual void onTimerFired(); + // Virtual for testing. virtual double monotonicallyIncreasingTimeMs() const; protected: CCDelayBasedTimeSource(double intervalMs, CCThread*); - void onTick(); - void updateState(); - void postTickTask(long long delay); + void postNextTickTask(double nowMs); enum State { STATE_INACTIVE, @@ -60,10 +62,12 @@ protected: STATE_ACTIVE, }; CCTimeSourceClient* m_client; + bool m_hasTickTarget; double m_intervalMs; double m_tickTarget; State m_state; CCThread* m_thread; + CCTimer m_timer; }; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp index 21fe68438..6837f0a5c 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp @@ -129,15 +129,13 @@ PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const void CCLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState* sharedQuadState) { - IntRect layerRect(IntPoint(), bounds()); - quadList.append(CCCustomLayerDrawQuad::create(sharedQuadState, layerRect, this)); + IntRect quadRect(IntPoint(), bounds()); + quadList.append(CCCustomLayerDrawQuad::create(sharedQuadState, quadRect, this)); } void CCLayerImpl::appendDebugBorderQuad(CCQuadList& quadList, const CCSharedQuadState* sharedQuadState) const { - if (!debugBorderColor().alpha()) - return; - if (debugBorderWidth() <= 0) + if (!hasDebugBorders()) return; IntRect layerRect(IntPoint(), bounds()); @@ -176,7 +174,13 @@ const IntRect CCLayerImpl::getDrawRect() const TransformationMatrix CCLayerImpl::quadTransform() const { - return drawTransform(); + TransformationMatrix quadTransformation = drawTransform(); + + float offsetX = -0.5 * bounds().width(); + float offsetY = -0.5 * bounds().height(); + quadTransformation.translate(offsetX, offsetY); + + return quadTransformation; } void CCLayerImpl::writeIndent(TextStream& ts, int indent) @@ -420,6 +424,11 @@ void CCLayerImpl::setDebugBorderWidth(float debugBorderWidth) m_layerPropertyChanged = true; } +bool CCLayerImpl::hasDebugBorders() const +{ + return debugBorderColor().alpha() && debugBorderWidth() > 0; +} + void CCLayerImpl::setContentBounds(const IntSize& contentBounds) { if (m_contentBounds == contentBounds) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h index a18fd4420..0136b01f8 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h @@ -132,6 +132,7 @@ public: Color debugBorderColor() const { return m_debugBorderColor; } void setDebugBorderWidth(float); float debugBorderWidth() const { return m_debugBorderWidth; } + bool hasDebugBorders() const; CCRenderSurface* renderSurface() const { return m_renderSurface.get(); } void createRenderSurface(); diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp new file mode 100644 index 000000000..0767ff0e7 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "cc/CCLayerIterator.h" + +#include "LayerChromium.h" +#include "RenderSurfaceChromium.h" +#include "cc/CCLayerImpl.h" +#include "cc/CCRenderSurface.h" + +namespace WebCore { + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::BackToFront::begin(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + pos.targetRenderSurfaceLayerIndex = 0; + pos.currentLayerIndex = CCLayerIteratorPositionValue::LayerIndexRepresentingTargetRenderSurface; + + m_highestTargetRenderSurfaceLayer = 0; +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::BackToFront::end(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + pos.targetRenderSurfaceLayerIndex = CCLayerIteratorPositionValue::InvalidTargetRenderSurfaceLayerIndex; + pos.currentLayerIndex = 0; +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::BackToFront::next(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + // If the current layer has a RS, move to its layer list. Otherwise, visit the next layer in the current RS layer list. + if (pos.currentLayerRepresentsContributingRenderSurface()) { + // Save our position in the childLayer list for the RenderSurface, then jump to the next RenderSurface. Save where we + // came from in the next RenderSurface so we can get back to it. + pos.targetRenderSurface()->m_currentLayerIndexHistory = pos.currentLayerIndex; + int previousTargetRenderSurfaceLayer = pos.targetRenderSurfaceLayerIndex; + + pos.targetRenderSurfaceLayerIndex = ++m_highestTargetRenderSurfaceLayer; + pos.currentLayerIndex = CCLayerIteratorPositionValue::LayerIndexRepresentingTargetRenderSurface; + + pos.targetRenderSurface()->m_targetRenderSurfaceLayerIndexHistory = previousTargetRenderSurfaceLayer; + } else { + ++pos.currentLayerIndex; + + int targetRenderSurfaceNumChildren = pos.targetRenderSurfaceChildren().size(); + while (pos.currentLayerIndex == targetRenderSurfaceNumChildren) { + // Jump back to the previous RenderSurface, and get back the position where we were in that list, and move to the next position there. + if (!pos.targetRenderSurfaceLayerIndex) { + // End of the list + pos.targetRenderSurfaceLayerIndex = CCLayerIteratorPositionValue::InvalidTargetRenderSurfaceLayerIndex; + pos.currentLayerIndex = 0; + return; + } + pos.targetRenderSurfaceLayerIndex = pos.targetRenderSurface()->m_targetRenderSurfaceLayerIndexHistory; + pos.currentLayerIndex = pos.targetRenderSurface()->m_currentLayerIndexHistory + 1; + + targetRenderSurfaceNumChildren = pos.targetRenderSurfaceChildren().size(); + } + } +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::FrontToBack::begin(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + pos.targetRenderSurfaceLayerIndex = 0; + pos.currentLayerIndex = pos.targetRenderSurfaceChildren().size() - 1; + goToHighestInSubtree(pos); +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::FrontToBack::end(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + pos.targetRenderSurfaceLayerIndex = CCLayerIteratorPositionValue::InvalidTargetRenderSurfaceLayerIndex; + pos.currentLayerIndex = 0; +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::FrontToBack::next(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + // Moves to the previous layer in the current RS layer list. Then we check if the + // new current layer has its own RS, in which case there are things in that RS layer list that are higher, so + // we find the highest layer in that subtree. + // If we move back past the front of the list, we jump up to the previous RS layer list, picking up again where we + // had previously recursed into the current RS layer list. + + if (!pos.currentLayerRepresentsTargetRenderSurface()) { + // Subtracting one here will eventually cause the current layer to become that layer + // representing the target render surface. + --pos.currentLayerIndex; + goToHighestInSubtree(pos); + } else { + while (pos.currentLayerRepresentsTargetRenderSurface()) { + if (!pos.targetRenderSurfaceLayerIndex) { + // End of the list + pos.targetRenderSurfaceLayerIndex = CCLayerIteratorPositionValue::InvalidTargetRenderSurfaceLayerIndex; + pos.currentLayerIndex = 0; + return; + } + pos.targetRenderSurfaceLayerIndex = pos.targetRenderSurface()->m_targetRenderSurfaceLayerIndexHistory; + pos.currentLayerIndex = pos.targetRenderSurface()->m_currentLayerIndexHistory; + } + } +} + +template <typename LayerType, typename RenderSurfaceType> +void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIteratorPosition<LayerType, RenderSurfaceType>& pos) +{ + if (pos.currentLayerRepresentsTargetRenderSurface()) + return; + while (pos.currentLayerRepresentsContributingRenderSurface()) { + // Save where we were in the current target surface, move to the next one, and save the target surface that we + // came from there so we can go back to it. + pos.targetRenderSurface()->m_currentLayerIndexHistory = pos.currentLayerIndex; + int previousTargetRenderSurfaceLayer = pos.targetRenderSurfaceLayerIndex; + + for (LayerType* layer = pos.currentLayer(); pos.targetRenderSurfaceLayer() != layer; ++pos.targetRenderSurfaceLayerIndex) { } + pos.currentLayerIndex = pos.targetRenderSurfaceChildren().size() - 1; + + pos.targetRenderSurface()->m_targetRenderSurfaceLayerIndexHistory = previousTargetRenderSurfaceLayer; + } +} + +// Declare each of the above functions for LayerChromium and CCLayerImpl classes so that they are linked. +template void CCLayerIteratorActions::BackToFront::begin(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); +template void CCLayerIteratorActions::BackToFront::end(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); +template void CCLayerIteratorActions::BackToFront::next(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); + +template void CCLayerIteratorActions::BackToFront::begin(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); +template void CCLayerIteratorActions::BackToFront::end(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); +template void CCLayerIteratorActions::BackToFront::next(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); + +template void CCLayerIteratorActions::FrontToBack::next(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); +template void CCLayerIteratorActions::FrontToBack::end(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); +template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); +template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIteratorPosition<LayerChromium, RenderSurfaceChromium>&); + +template void CCLayerIteratorActions::FrontToBack::next(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); +template void CCLayerIteratorActions::FrontToBack::end(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); +template void CCLayerIteratorActions::FrontToBack::begin(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); +template void CCLayerIteratorActions::FrontToBack::goToHighestInSubtree(CCLayerIteratorPosition<CCLayerImpl, CCRenderSurface>&); + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h new file mode 100644 index 000000000..8f412c44d --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIterator.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CCLayerIterator_h +#define CCLayerIterator_h + +#include "cc/CCLayerIteratorPosition.h" + +#include <wtf/PassOwnPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +// These classes provide means to iterate over the RenderSurface-Layer tree. + +// Example code follows, for a tree of LayerChromium/RenderSurfaceChromium objects. See below for details. +// +// void doStuffOnLayers(const Vector<RefPtr<LayerChromium> >& renderSurfaceLayerList) +// { +// typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType; +// +// CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); +// for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) { +// // Only one of these will be true +// if (it.representsTargetRenderSurface()) +// foo(*it); // *it is a layer representing a target RenderSurface +// if (it.representsContributingRenderSurface()) +// bar(*it); // *it is a layer representing a RenderSurface that contributes to the layer's target RenderSurface +// if (it.representsItself()) +// baz(*it); // *it is a layer representing itself, as it contributes to its own target RenderSurface +// } +// } + +// A RenderSurface R may be referred to in one of two different contexts. One RenderSurface is "current" at any time, for +// whatever operation is being performed. This current surface is referred to as a target surface. For example, when R is +// being painted it would be the target surface. Once R has been painted, its contents may be included into another +// surface S. While S is considered the target surface when it is being painted, R is called a contributing surface +// in this context as it contributes to the content of the target surface S. +// +// The iterator's current position in the tree always points to some layer. The state of the iterator indicates the role of the +// layer, and will be one of the following three states. A single layer L will appear in the iteration process in at least one, +// and possibly all, of these states. +// 1. Representing the target surface: The iterator in this state, pointing at layer L, indicates that the target RenderSurface +// is now the surface owned by L. This will occur exactly once for each RenderSurface in the tree. +// 2. Representing a contributing surface: The iterator in this state, pointing at layer L, refers to the RenderSurface owned +// by L as a contributing surface, without changing the current target RenderSurface. +// 3. Representing itself: The iterator in this state, pointing at layer L, refers to the layer itself, as a child of the +// current target RenderSurface. +// +// The BackToFront iterator will return a layer representing the target surface before returning layers representing themselves +// as children of the current target surface. Whereas the FrontToBack ordering will iterate over children layers of a surface +// before the layer representing the surface as a target surface. +// +// To use the iterators: +// +// Create a stepping iterator and end iterator by calling CCLayerIterator::begin() and CCLayerIterator::end() and passing in the +// list of layers owning target RenderSurfaces. Step through the tree by incrementing the stepping iterator while it is != to +// the end iterator. At each step the iterator knows what the layer is representing, and you can query the iterator to decide +// what actions to perform with the layer given what it represents. + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// An iterator class for walking over layers in the RenderSurface-Layer tree. +template <typename LayerType, typename RenderSurfaceType, typename IteratorActionType> +class CCLayerIterator { + typedef CCLayerIterator<LayerType, RenderSurfaceType, IteratorActionType> CCLayerIteratorType; + +public: + CCLayerIterator() { } + + static CCLayerIteratorType begin(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, true); } + static CCLayerIteratorType end(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList) { return CCLayerIteratorType(renderSurfaceLayerList, false); } + + CCLayerIteratorType& operator++() { ASSERT(m_actions); m_actions->next(m_position); return *this; } + bool operator==(const CCLayerIteratorType& other) const { return m_position == other.m_position; } + bool operator!=(const CCLayerIteratorType& other) const { return !(*this == other); } + + LayerType* operator->() const { return m_position.currentLayer(); } + LayerType* operator*() const { return m_position.currentLayer(); } + + bool representsTargetRenderSurface() const { return m_position.currentLayerRepresentsTargetRenderSurface(); } + bool representsContributingRenderSurface() const { return !representsTargetRenderSurface() && m_position.currentLayerRepresentsContributingRenderSurface(); } + bool representsItself() const { return !representsTargetRenderSurface() && !representsContributingRenderSurface(); } + + LayerType* targetRenderSurfaceLayer() const { return m_position.targetRenderSurfaceLayer(); } + +private: + CCLayerIterator(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList, bool start) + : m_position(renderSurfaceLayerList) + , m_actions(adoptPtr(new IteratorActionType())) + { + if (start && !renderSurfaceLayerList->isEmpty()) + m_actions->begin(m_position); + else + m_actions->end(m_position); + } + + CCLayerIteratorPosition<LayerType, RenderSurfaceType> m_position; + OwnPtr<IteratorActionType> m_actions; +}; + +// Orderings for iterating over the RenderSurface-Layer tree. +struct CCLayerIteratorActions { + // Walks layers sorted by z-order from back to front. + class BackToFront { + public: + template <typename LayerType, typename RenderSurfaceType> + void begin(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + template <typename LayerType, typename RenderSurfaceType> + void end(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + template <typename LayerType, typename RenderSurfaceType> + void next(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + private: + int m_highestTargetRenderSurfaceLayer; + }; + + // Walks layers sorted by z-order from front to back + class FrontToBack { + public: + template <typename LayerType, typename RenderSurfaceType> + void begin(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + template <typename LayerType, typename RenderSurfaceType> + void end(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + template <typename LayerType, typename RenderSurfaceType> + void next(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + + private: + template <typename LayerType, typename RenderSurfaceType> + void goToHighestInSubtree(CCLayerIteratorPosition<LayerType, RenderSurfaceType>&); + }; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerIteratorPosition.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIteratorPosition.h new file mode 100644 index 000000000..b1f63c45f --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerIteratorPosition.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CCLayerIteratorPosition_h +#define CCLayerIteratorPosition_h + +#include "cc/CCLayerTreeHostCommon.h" + +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +// Non-templated constants +struct CCLayerIteratorPositionValue { + static const int InvalidTargetRenderSurfaceLayerIndex = -1; + // This must be -1 since the iterator action code assumes that this value can be + // reached by subtracting one from the position of the first layer in the current + // target surface's child layer list, which is 0. + static const int LayerIndexRepresentingTargetRenderSurface = -1; +}; + +// A struct to hold the iterator's current position, which is passed to the various CCLayerIteratorAction functions, for them to +// read and update. This struct exists so the templated action functions don't need to access the CCLayerIterator class. +// +// There is a 1:1 relationship between an instance of the CCLayerIteratorPosition class and a CCLayerIteratorActions::Foo class, +// so an iterator action class can hold extra position data, if required, in its own class instance. +// +// The current position of the iterator is held in two integer variables. +// - The targetRenderSurfaceLayerIndex is a position in the renderSurfaceLayerList. This points to a layer which owns the current +// target surface. This is a value from 0 to n-1 (n = size of renderSurfaceLayerList = number of surfaces). A value outside of +// this range (for example, CCLayerIteratorPositionValue::InvalidTargetRenderSurfaceLayerIndex) is used to indicate a position +// outside the bounds of the tree. +// - The currentLayerIndex is a position in the list of layers that are children of the current target surface. When pointing to +// one of these layers, this is a value from 0 to n-1 (n = number of children). Since the iterator must also stop at the layers +// representing the target surface, this is done by setting the currentLayerIndex to a value of +// CCLayerIteratorPositionValue::LayerRepresentingTargetRenderSurface. +template<typename LayerType, typename RenderSurfaceType> +struct CCLayerIteratorPosition { + CCLayerIteratorPosition() : renderSurfaceLayerList(0) { } + explicit CCLayerIteratorPosition(const Vector<RefPtr<LayerType> >* renderSurfaceLayerList) : renderSurfaceLayerList(renderSurfaceLayerList) { } + + inline LayerType* currentLayer() const { return currentLayerRepresentsTargetRenderSurface() ? targetRenderSurfaceLayer() : targetRenderSurfaceChildren()[currentLayerIndex].get(); } + + inline bool currentLayerRepresentsContributingRenderSurface() const { return CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerType>(currentLayer(), targetRenderSurfaceLayer()->id()); } + inline bool currentLayerRepresentsTargetRenderSurface() const { return currentLayerIndex == CCLayerIteratorPositionValue::LayerIndexRepresentingTargetRenderSurface; } + + inline LayerType* targetRenderSurfaceLayer() const { return (*renderSurfaceLayerList)[targetRenderSurfaceLayerIndex].get(); } + inline RenderSurfaceType* targetRenderSurface() const { return targetRenderSurfaceLayer()->renderSurface(); } + inline const Vector<RefPtr<LayerType> >& targetRenderSurfaceChildren() const { return targetRenderSurface()->layerList(); } + + inline bool operator==(const CCLayerIteratorPosition& other) const + { + return targetRenderSurfaceLayerIndex == other.targetRenderSurfaceLayerIndex + && currentLayerIndex == other.currentLayerIndex; + } + + const Vector<RefPtr<LayerType> >* renderSurfaceLayerList; + int targetRenderSurfaceLayerIndex; + int currentLayerIndex; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp index 379d16083..8663ec0ac 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp @@ -31,6 +31,7 @@ #include "LayerRendererChromium.h" #include "TraceEvent.h" #include "TreeSynchronizer.h" +#include "cc/CCLayerIterator.h" #include "cc/CCLayerTreeHostCommon.h" #include "cc/CCLayerTreeHostImpl.h" #include "cc/CCSingleThreadProxy.h" @@ -156,7 +157,7 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl) hostImpl->setSourceFrameNumber(frameNumber()); hostImpl->setHaveWheelEventHandlers(m_haveWheelEventHandlers); - hostImpl->setViewport(viewportSize()); + hostImpl->setViewportSize(viewportSize()); hostImpl->setPageScaleFactorAndLimits(pageScale(), m_minPageScale, m_maxPageScale); m_frameNumber++; @@ -247,8 +248,11 @@ void CCLayerTreeHost::setRootLayer(PassRefPtr<LayerChromium> rootLayer) setNeedsCommit(); } -void CCLayerTreeHost::setViewport(const IntSize& viewportSize) +void CCLayerTreeHost::setViewportSize(const IntSize& viewportSize) { + if (viewportSize == m_viewportSize) + return; + contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(viewportSize)); contentsTextureManager()->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(viewportSize)); m_viewportSize = viewportSize; @@ -428,57 +432,40 @@ void CCLayerTreeHost::paintMaskAndReplicaForRenderSurface(LayerChromium* renderS void CCLayerTreeHost::paintLayerContents(const LayerList& renderSurfaceLayerList, PaintType paintType) { - for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { - LayerChromium* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); - RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); - ASSERT(renderSurface); - ASSERT(renderSurface->drawOpacity()); - - paintMaskAndReplicaForRenderSurface(renderSurfaceLayer, paintType); - - const LayerList& layerList = renderSurface->layerList(); - for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { - LayerChromium* layer = layerList[layerIndex].get(); - - // Layers that start a new render surface will be painted when the render - // surface's list is processed. - if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerChromium>(layer, renderSurfaceLayer->id())) - continue; - - ASSERT(!layer->bounds().isEmpty()); - - paintContentsIfDirty(layer, paintType); + // Use FrontToBack to allow for testing occlusion and performing culling during the tree walk. + typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::FrontToBack> CCLayerIteratorType; + + CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); + for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) { + if (it.representsTargetRenderSurface()) { + ASSERT(it->renderSurface()->drawOpacity()); + paintMaskAndReplicaForRenderSurface(*it, paintType); + } else if (it.representsItself()) { + ASSERT(!it->bounds().isEmpty()); + paintContentsIfDirty(*it, paintType); } } } void CCLayerTreeHost::updateCompositorResources(GraphicsContext3D* context, CCTextureUpdater& updater) { - for (int surfaceIndex = m_updateList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { - LayerChromium* renderSurfaceLayer = m_updateList[surfaceIndex].get(); - RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); - ASSERT(renderSurface); - ASSERT(renderSurface->drawOpacity()); - - if (renderSurfaceLayer->maskLayer()) - renderSurfaceLayer->maskLayer()->updateCompositorResources(context, updater); - - if (renderSurfaceLayer->replicaLayer()) { - renderSurfaceLayer->replicaLayer()->updateCompositorResources(context, updater); - - if (renderSurfaceLayer->replicaLayer()->maskLayer()) - renderSurfaceLayer->replicaLayer()->maskLayer()->updateCompositorResources(context, updater); - } - - const LayerList& layerList = renderSurface->layerList(); - for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { - LayerChromium* layer = layerList[layerIndex].get(); - - if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<LayerChromium>(layer, renderSurfaceLayer->id())) - continue; - - layer->updateCompositorResources(context, updater); - } + // Use BackToFront since it's cheap and this isn't order-dependent. + typedef CCLayerIterator<LayerChromium, RenderSurfaceChromium, CCLayerIteratorActions::BackToFront> CCLayerIteratorType; + + CCLayerIteratorType end = CCLayerIteratorType::end(&m_updateList); + for (CCLayerIteratorType it = CCLayerIteratorType::begin(&m_updateList); it != end; ++it) { + if (it.representsTargetRenderSurface()) { + ASSERT(it->renderSurface()->drawOpacity()); + if (it->maskLayer()) + it->maskLayer()->updateCompositorResources(context, updater); + + if (it->replicaLayer()) { + it->replicaLayer()->updateCompositorResources(context, updater); + if (it->replicaLayer()->maskLayer()) + it->replicaLayer()->maskLayer()->updateCompositorResources(context, updater); + } + } else if (it.representsItself()) + it->updateCompositorResources(context, updater); } } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h index 4f293eca5..2f989bcf6 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h @@ -169,7 +169,7 @@ public: const CCSettings& settings() const { return m_settings; } - void setViewport(const IntSize& viewportSize); + void setViewportSize(const IntSize&); const IntSize& viewportSize() const { return m_viewportSize; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp index fc08f71ee..b4e7be415 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp @@ -33,6 +33,7 @@ #include "RenderSurfaceChromium.h" #include "TransformationMatrix.h" #include "cc/CCLayerImpl.h" +#include "cc/CCLayerIterator.h" #include "cc/CCLayerSorter.h" #include "cc/CCRenderSurface.h" @@ -469,15 +470,14 @@ static bool calculateDrawTransformsAndVisibilityInternal(LayerType* layer, Layer template<typename LayerType, typename RenderSurfaceType> static void walkLayersAndCalculateVisibleLayerRects(const Vector<RefPtr<LayerType> >& renderSurfaceLayerList) { - for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { - LayerType* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); - RenderSurfaceType* renderSurface = renderSurfaceLayer->renderSurface(); - - Vector<RefPtr<LayerType> >& layerList = renderSurface->layerList(); - for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { - LayerType* layer = layerList[layerIndex].get(); - IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<LayerType>(layer); - layer->setVisibleLayerRect(visibleLayerRect); + // Use BackToFront since it's cheap and this isn't order-dependent. + typedef CCLayerIterator<LayerType, RenderSurfaceType, CCLayerIteratorActions::BackToFront> CCLayerIteratorType; + + CCLayerIteratorType end = CCLayerIteratorType::end(&renderSurfaceLayerList); + for (CCLayerIteratorType it = CCLayerIteratorType::begin(&renderSurfaceLayerList); it != end; ++it) { + if (!it.representsTargetRenderSurface()) { + IntRect visibleLayerRect = CCLayerTreeHostCommon::calculateVisibleLayerRect<LayerType>(*it); + it->setVisibleLayerRect(visibleLayerRect); } } } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp index f6cfaa54f..02186caaf 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp @@ -187,7 +187,7 @@ static FloatRect damageInSurfaceSpace(CCLayerImpl* renderSurfaceLayer, const Flo return surfaceDamageRect; } -void CCLayerTreeHostImpl::calculateRenderPasses(Vector<OwnPtr<CCRenderPass> >& passes) +void CCLayerTreeHostImpl::calculateRenderPasses(CCRenderPassList& passes) { CCLayerList renderSurfaceLayerList; renderSurfaceLayerList.append(rootLayer()); @@ -238,6 +238,12 @@ void CCLayerTreeHostImpl::calculateRenderPasses(Vector<OwnPtr<CCRenderPass> >& p } } +void CCLayerTreeHostImpl::optimizeRenderPasses(CCRenderPassList& passes) +{ + for (unsigned i = 0; i < passes.size(); ++i) + passes[i]->optimizeQuads(); +} + void CCLayerTreeHostImpl::drawLayers() { TRACE_EVENT("CCLayerTreeHostImpl::drawLayers", this, 0); @@ -246,9 +252,11 @@ void CCLayerTreeHostImpl::drawLayers() if (!rootLayer()) return; - Vector<OwnPtr<CCRenderPass> > passes; + CCRenderPassList passes; calculateRenderPasses(passes); + optimizeRenderPasses(passes); + m_layerRenderer->beginDrawingFrame(); for (size_t i = 0; i < passes.size(); ++i) m_layerRenderer->drawRenderPass(passes[i].get()); @@ -353,7 +361,7 @@ bool CCLayerTreeHostImpl::initializeLayerRenderer(PassRefPtr<GraphicsContext3D> return m_layerRenderer; } -void CCLayerTreeHostImpl::setViewport(const IntSize& viewportSize) +void CCLayerTreeHostImpl::setViewportSize(const IntSize& viewportSize) { if (viewportSize == m_viewportSize) return; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h index fe774ee00..e4d006d4f 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h @@ -107,7 +107,7 @@ public: int sourceFrameNumber() const { return m_sourceFrameNumber; } void setSourceFrameNumber(int frameNumber) { m_sourceFrameNumber = frameNumber; } - void setViewport(const IntSize& viewportSize); + void setViewportSize(const IntSize&); const IntSize& viewportSize() const { return m_viewportSize; } void setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale); @@ -133,7 +133,8 @@ private: void adjustScrollsForPageScaleChange(float); void updateMaxScrollPosition(); void trackDamageForAllSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList); - void calculateRenderPasses(Vector<OwnPtr<CCRenderPass> >&); + void calculateRenderPasses(CCRenderPassList&); + void optimizeRenderPasses(CCRenderPassList&); OwnPtr<LayerRendererChromium> m_layerRenderer; RefPtr<CCLayerImpl> m_rootLayerImpl; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp new file mode 100644 index 000000000..4a8b85130 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "cc/CCQuadCuller.h" + +#include "Region.h" +#include "TransformationMatrix.h" +#include "cc/CCCustomLayerDrawQuad.h" +#include "cc/CCLayerImpl.h" +#include "cc/CCRenderPass.h" +#include "cc/CCRenderSurfaceDrawQuad.h" + +namespace std { + +// Specialize for OwnPtr<CCDrawQuad> since Vector doesn't know how to reverse a Vector of OwnPtr<T> in general. +template<> +void swap(OwnPtr<WebCore::CCDrawQuad>& a, OwnPtr<WebCore::CCDrawQuad>& b) +{ + a.swap(b); +} + +} + +namespace WebCore { + +static bool regionContainsRect(const Region& region, const IntRect& rect) +{ + Region rectRegion(rect); + Region intersectRegion(intersect(region, rectRegion)); + + if (intersectRegion.isEmpty()) + return false; + + rectRegion.subtract(intersectRegion); + return rectRegion.isEmpty(); +} + +void CCQuadCuller::cullOccludedQuads(CCQuadList& quadList) +{ + if (!quadList.size()) + return; + + CCQuadList culledList; + culledList.reserveCapacity(quadList.size()); + + Region opaqueCoverageThusFar; + + for (int i = quadList.size() - 1; i >= 0; --i) { + CCDrawQuad* drawQuad = quadList[i].get(); + + IntRect quadRect(drawQuad->quadTransform().mapRect(drawQuad->quadRect())); + + bool keepQuad = !regionContainsRect(opaqueCoverageThusFar, quadRect); + + if (keepQuad && drawQuad->drawsOpaque() && drawQuad->isLayerAxisAlignedIntRect()) + opaqueCoverageThusFar.unite(Region(quadRect)); + + if (keepQuad) + culledList.append(quadList[i].release()); + } + quadList.clear(); // Release anything that remains. + + culledList.reverse(); + quadList.swap(culledList); +} + +} // namespace WebCore +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h new file mode 100644 index 000000000..7179285ac --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCQuadCuller.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 CCQuadCuller_h +#define CCQuadCuller_h + +#include "cc/CCRenderPass.h" + +namespace WebCore { + +class CCQuadCuller { +public: + static void cullOccludedQuads(CCQuadList&); + +private: + // Make non-instantiable. + CCQuadCuller() { } +}; + +} +#endif // CCQuadCuller_h diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp index 71adc4b3e..6f51fbcde 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.cpp @@ -28,6 +28,7 @@ #include "cc/CCRenderPass.h" #include "cc/CCLayerImpl.h" +#include "cc/CCQuadCuller.h" #include "cc/CCRenderSurfaceDrawQuad.h" #include "cc/CCSharedQuadState.h" @@ -63,4 +64,9 @@ void CCRenderPass::appendQuadsForRenderSurfaceLayer(CCLayerImpl* layer) m_sharedQuadStateList.append(sharedQuadState.release()); } +void CCRenderPass::optimizeQuads() +{ + CCQuadCuller::cullOccludedQuads(m_quadList); +} + } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h index 16e072e80..9fb77166c 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderPass.h @@ -46,6 +46,8 @@ public: void appendQuadsForLayer(CCLayerImpl*); void appendQuadsForRenderSurfaceLayer(CCLayerImpl*); + void optimizeQuads(); + const CCQuadList& quadList() const { return m_quadList; } CCRenderSurface* targetSurface() const { return m_targetSurface; } @@ -61,6 +63,8 @@ private: FloatRect m_surfaceDamageRect; }; +typedef Vector<OwnPtr<CCRenderPass> > CCRenderPassList; + } #endif diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h index a8e87a9f9..ab8386d5d 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h +++ b/Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.h @@ -129,6 +129,11 @@ private: // Stored in the "surface space" where this damage can be used for scissoring. FloatRect m_damageRect; + + // For CCLayerIteratorActions + int m_targetRenderSurfaceLayerIndexHistory; + int m_currentLayerIndexHistory; + friend struct CCLayerIteratorActions; }; } diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp index 6ccb40704..5849ef1eb 100644 --- a/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp +++ b/Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp @@ -30,6 +30,7 @@ #include "cc/CCTiledLayerImpl.h" #include "LayerRendererChromium.h" +#include "cc/CCDebugBorderDrawQuad.h" #include "cc/CCSolidColorDrawQuad.h" #include "cc/CCTileDrawQuad.h" #include <wtf/text/WTFString.h> @@ -38,6 +39,9 @@ using namespace std; namespace WebCore { +static const int debugTileBorderWidth = 1; +static const int debugTileBorderAlpha = 100; + class ManagedTexture; class DrawableTile : public CCLayerTilingData::Tile { @@ -156,6 +160,11 @@ void CCTiledLayerImpl::appendQuads(CCQuadList& quadList, const CCSharedQuadState const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST; quadList.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tile->textureId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA)); + + if (hasDebugBorders()) { + Color color(debugBorderColor().red(), debugBorderColor().green(), debugBorderColor().blue(), debugTileBorderAlpha); + quadList.append(CCDebugBorderDrawQuad::create(sharedQuadState, tileRect, color, debugTileBorderWidth)); + } } } } diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index f9a86eb17..027642be7 100644 --- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -273,13 +273,6 @@ void FEGaussianBlur::determineAbsolutePaintRect() void FEGaussianBlur::platformApplySoftware() { -#if USE(SKIA) - if (filter()->renderingMode() == Accelerated) { - platformApplySkia(); - return; - } -#endif - FilterEffect* in = inputEffect(0); ByteArray* srcPixelArray = createPremultipliedImageResult(); diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h index 7f6c3bbee..b295d3608 100644 --- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h +++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h @@ -74,7 +74,9 @@ private: inline void platformApplyGeneric(ByteArray* srcPixelArray, ByteArray* tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize); inline void platformApplyNeon(ByteArray* srcPixelArray, ByteArray* tmpPixelArray, unsigned kernelSizeX, unsigned kernelSizeY, IntSize& paintSize); - void platformApplySkia(); +#if USE(SKIA) + virtual bool platformApplySkia(); +#endif float m_stdX; float m_stdY; diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp index 6516faadc..fbeb4bbcb 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -104,6 +104,10 @@ void FilterEffect::apply() determineAbsolutePaintRect(); // Add platform specific apply functions here and return earlier. +#if USE(SKIA) + if (platformApplySkia()) + return; +#endif platformApplySoftware(); } diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h index 073010d27..1bae4ca0a 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.h +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h @@ -87,6 +87,9 @@ public: void apply(); virtual void platformApplySoftware() = 0; +#if USE(SKIA) + virtual bool platformApplySkia() { return false; } +#endif virtual void dump() = 0; virtual void determineAbsolutePaintRect(); diff --git a/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp new file mode 100644 index 000000000..0fd07776e --- /dev/null +++ b/Source/WebCore/platform/graphics/filters/skia/FEColorMatrixSkia.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#if ENABLE(FILTERS) && USE(SKIA) +#include "FEColorMatrix.h" + +#include "NativeImageSkia.h" +#include "SkColorMatrixFilter.h" + +namespace WebCore { + +static void saturateMatrix(float s, SkScalar matrix[20]) +{ + matrix[0] = 0.213f + 0.787f * s; + matrix[1] = 0.715f - 0.715f * s; + matrix[2] = 0.072f - 0.072f * s; + matrix[3] = matrix[4] = 0; + matrix[5] = 0.213f - 0.213f * s; + matrix[6] = 0.715f + 0.285f * s; + matrix[7] = 0.072f - 0.072f * s; + matrix[8] = matrix[9] = 0; + matrix[10] = 0.213f - 0.213f * s; + matrix[11] = 0.715f - 0.715f * s; + matrix[12] = 0.072f + 0.928f * s; + matrix[13] = matrix[14] = 0; + matrix[15] = matrix[16] = matrix[17] = 0; + matrix[18] = 1; + matrix[19] = 0; +} + +static void hueRotateMatrix(float hue, SkScalar matrix[20]) +{ + float cosHue = cosf(hue * piFloat / 180); + float sinHue = sinf(hue * piFloat / 180); + matrix[0] = 0.213f + cosHue * 0.787f - sinHue * 0.213f; + matrix[1] = 0.715f - cosHue * 0.715f - sinHue * 0.715f; + matrix[2] = 0.072f - cosHue * 0.072f + sinHue * 0.928f; + matrix[3] = matrix[4] = 0; + matrix[5] = 0.213f - cosHue * 0.213f + sinHue * 0.143f; + matrix[6] = 0.715f + cosHue * 0.285f + sinHue * 0.140f; + matrix[7] = 0.072f - cosHue * 0.072f - sinHue * 0.283f; + matrix[8] = matrix[9] = 0; + matrix[10] = 0.213f - cosHue * 0.213f - sinHue * 0.787f; + matrix[11] = 0.715f - cosHue * 0.715f + sinHue * 0.715f; + matrix[12] = 0.072f + cosHue * 0.928f + sinHue * 0.072f; + matrix[13] = matrix[14] = 0; + matrix[15] = matrix[16] = matrix[17] = 0; + matrix[18] = 1; + matrix[19] = 0; +} + +static void luminanceToAlphaMatrix(SkScalar matrix[20]) +{ + memset(matrix, 0, 20 * sizeof(SkScalar)); + matrix[15] = 0.2125f; + matrix[16] = 0.7154f; + matrix[17] = 0.0721f; +} + +bool FEColorMatrix::platformApplySkia() +{ + ImageBuffer* resultImage = createImageBufferResult(); + if (!resultImage) + return false; + + FilterEffect* in = inputEffect(0); + + IntRect imageRect(IntPoint(), absolutePaintRect().size()); + + SkScalar matrix[20]; + + switch (m_type) { + case FECOLORMATRIX_TYPE_UNKNOWN: + break; + case FECOLORMATRIX_TYPE_MATRIX: + for (int i = 0; i < 20; ++i) + matrix[i] = m_values[i]; + + matrix[4] *= SkScalar(255); + matrix[9] *= SkScalar(255); + matrix[14] *= SkScalar(255); + matrix[19] *= SkScalar(255); + break; + case FECOLORMATRIX_TYPE_SATURATE: + saturateMatrix(m_values[0], matrix); + break; + case FECOLORMATRIX_TYPE_HUEROTATE: + hueRotateMatrix(m_values[0], matrix); + break; + case FECOLORMATRIX_TYPE_LUMINANCETOALPHA: + luminanceToAlphaMatrix(matrix); + break; + } + + RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); + NativeImageSkia* nativeImage = image->nativeImageForCurrentFrame(); + if (!nativeImage) + return false; + + SkCanvas* canvas = resultImage->context()->platformContext()->canvas(); + SkPaint paint; + paint.setColorFilter(new SkColorMatrixFilter(matrix))->unref(); + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + canvas->drawBitmap(nativeImage->bitmap(), 0, 0, &paint); + return true; +} + +} // namespace WebCore + +#endif // ENABLE(FILTERS) && USE(SKIA) diff --git a/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp b/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp index ceb1146c7..4b36751fa 100644 --- a/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp +++ b/Source/WebCore/platform/graphics/filters/skia/FEGaussianBlurSkia.cpp @@ -32,11 +32,11 @@ namespace WebCore { -void FEGaussianBlur::platformApplySkia() +bool FEGaussianBlur::platformApplySkia() { ImageBuffer* resultImage = createImageBufferResult(); if (!resultImage) - return; + return false; FilterEffect* in = inputEffect(0); @@ -57,7 +57,7 @@ void FEGaussianBlur::platformApplySkia() paint.setColor(0xFFFFFFFF); dstContext->drawImage(image.get(), ColorSpaceDeviceRGB, drawingRegion.location(), CompositeCopy); canvas->restore(); - return; + return true; } }; diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp index 3cc6be713..5d6e7fb26 100644 --- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp @@ -162,9 +162,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const return w; } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } diff --git a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp index 32f587c46..fd5e977ce 100644 --- a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp @@ -212,7 +212,7 @@ static void webkit_web_src_class_init(WebKitWebSrcClass* klass) static void webkit_web_src_init(WebKitWebSrc* src) { - GstPadTemplate* padTemplate = gst_static_pad_template_get(&srcTemplate); + GRefPtr<GstPadTemplate> padTemplate = adoptGRef(gst_static_pad_template_get(&srcTemplate)); WebKitWebSrcPrivate* priv = WEBKIT_WEB_SRC_GET_PRIVATE(src); src->priv = priv; @@ -232,7 +232,7 @@ static void webkit_web_src_init(WebKitWebSrc* src) GRefPtr<GstPad> targetPad = adoptGRef(gst_element_get_static_pad(GST_ELEMENT(priv->appsrc), "src")); - priv->srcpad = gst_ghost_pad_new_from_template("src", targetPad.get(), padTemplate); + priv->srcpad = gst_ghost_pad_new_from_template("src", targetPad.get(), padTemplate.get()); gst_element_add_pad(GST_ELEMENT(src), priv->srcpad); gst_pad_set_query_function(priv->srcpad, webKitWebSrcQuery); diff --git a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp index 5045e1070..f8bef5c00 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/FontPlatformDataHarfBuzz.cpp @@ -36,6 +36,7 @@ #include "PlatformSupport.h" #include "SkAdvancedTypefaceMetrics.h" +#include "SkFontHost.h" #include "SkPaint.h" #include "SkTypeface.h" @@ -116,9 +117,17 @@ int FontPlatformData::emSizeInFontUnits() const if (m_emSizeInFontUnits) return m_emSizeInFontUnits; + // FIXME: Switch to the SkTypeface::GetUnitsPerEm API once this becomes available. + // https://bugs.webkit.org/show_bug.cgi?id=75961 +#if OS(ANDROID) + // Android doesn't currently support Skia's getAdvancedTypefaceMetrics(), + // but it has access to another method to replace this functionality. + m_emSizeInFontUnits = SkFontHost::GetUnitsPerEm(m_typeface->uniqueID()); +#else SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo); m_emSizeInFontUnits = metrics->fEmSize; metrics->unref(); +#endif return m_emSizeInFontUnits; } diff --git a/Source/WebCore/platform/graphics/harfbuzz/SimpleFontDataSkia.cpp b/Source/WebCore/platform/graphics/harfbuzz/SimpleFontDataSkia.cpp index d02c12ada..782b02fa9 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/SimpleFontDataSkia.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/SimpleFontDataSkia.cpp @@ -236,9 +236,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const return round(SkScalarToFloat(width)); } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm index 17f226495..54c03f879 100644 --- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm @@ -467,32 +467,4 @@ bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters return true; } -static inline void decomposeToUTF16(UChar* buffer, unsigned& length, const UChar32 character) -{ - if (U_IS_BMP(character)) { - buffer[length] = character; - ++length; - return; - } - - buffer[length] = U16_LEAD(character); - buffer[length + 1] = U16_TRAIL(character); - length += 2; -} - -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - unsigned length = 0; - UChar buffer[4]; - - decomposeToUTF16(buffer, length, character); - decomposeToUTF16(buffer, length, selector); - ASSERT(length <= 4); - - CGGlyph glyphs[4]; - wkGetGlyphsForCharacters(platformData().cgFont(), buffer, glyphs, length); - if (glyphs[0]) - glyph = glyphs[0]; -} - } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp index f5c44e536..16a3b4a9c 100644 --- a/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp +++ b/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp @@ -1248,7 +1248,7 @@ String GraphicsContext3D::getProgramInfoLog(Platform3DObject program) return String(); GLsizei size = 0; - OwnArrayPtr<GLchar> info = adoptArrayPtr(static_cast<GLchar*>(fastMalloc(length))); + OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); ::glGetProgramInfoLog(program, length, &size, info.get()); return String(info.get()); @@ -1315,7 +1315,7 @@ String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader) return String(); GLsizei size = 0; - OwnArrayPtr<GLchar> info = adoptArrayPtr(static_cast<GLchar*>(fastMalloc(length))); + OwnArrayPtr<GLchar> info = adoptArrayPtr(new GLchar[length]); ::glGetShaderInfoLog(shader, length, &size, info.get()); return String(info.get()); diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp index 28ee2ba10..0ff7022e3 100644 --- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp +++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp @@ -41,6 +41,16 @@ #include <GL/gl.h> #endif +#if defined(TEXMAP_OPENGL_ES_2) +#include <EGL/egl.h> +#elif OS(WINDOWS) +#include <windows.h> +#elif OS(MAC_OS_X) +#include <AGL/agl.h> +#elif defined(XP_UNIX) +#include <GL/glx.h> +#endif + #if !defined(TEXMAP_OPENGL_ES_2) && !PLATFORM(QT) extern "C" { void glUniform1f(GLint, GLfloat); @@ -103,7 +113,60 @@ inline static void debugGLCommand(const char* command, int line) #endif struct TextureMapperGLData { - static struct GlobalGLData { + struct SharedGLData : public RefCounted<SharedGLData> { +#if defined(TEXMAP_OPENGL_ES_2) + typedef EGLContext GLContext; + static GLContext getCurrentGLContext() + { + return eglGetCurrentContext(); + } +#elif OS(WINDOWS) + typedef HGLRC GLContext; + static GLContext getCurrentGLContext() + { + return wglGetCurrentContext(); + } +#elif OS(MAC_OS_X) + typedef AGLContext GLContext; + static GLContext getCurrentGLContext() + { + return aglGetCurrentContext(); + } +#elif defined(XP_UNIX) + typedef GLXContext GLContext; + static GLContext getCurrentGLContext() + { + return glXGetCurrentContext(); + } +#else + // Default implementation for unknown opengl. + // Returns always increasing number and disables GL context data sharing. + typedef unsigned int GLContext; + static GLContext getCurrentGLContext() + { + static GLContext dummyContextCounter = 0; + return ++dummyContextCounter; + } + +#endif + + typedef HashMap<GLContext, SharedGLData*> GLContextDataMap; + static GLContextDataMap& glContextDataMap() + { + static GLContextDataMap map; + return map; + } + + static PassRefPtr<SharedGLData> currentSharedGLData() + { + GLContext currentGLConext = getCurrentGLContext(); + GLContextDataMap::iterator it = glContextDataMap().find(currentGLConext); + if (it != glContextDataMap().end()) + return it->second; + + return adoptRef(new SharedGLData(getCurrentGLContext())); + } + enum ShaderProgramIndex { NoProgram = -1, SimpleProgram, @@ -128,6 +191,9 @@ struct TextureMapperGLData { GLuint id; GLuint vertexAttrib; GLint vars[VariableCount]; + GLuint vertexShader; + GLuint fragmentShader; + ProgramInfo() : id(0) { } }; GLint getUniformLocation(ShaderProgramIndex prog, ShaderVariableIndex var, const char* name) @@ -149,16 +215,53 @@ struct TextureMapperGLData { GL_CMD(glLinkProgram(programID)) programs[index].vertexAttrib = glGetAttribLocation(programID, "InVertex"); programs[index].id = programID; + programs[index].vertexShader = vertexShader; + programs[index].fragmentShader = fragmentShader; + } + + void deleteShaderProgram(ShaderProgramIndex index) + { + ProgramInfo& programInfo = programs[index]; + GLuint programID = programInfo.id; + if (!programID) + return; + + GL_CMD(glDetachShader(programID, programInfo.vertexShader)) + GL_CMD(glDeleteShader(programInfo.vertexShader)) + GL_CMD(glDetachShader(programID, programInfo.fragmentShader)) + GL_CMD(glDeleteShader(programInfo.fragmentShader)) + GL_CMD(glDeleteProgram(programID)) } + void initializeShaders(); + ProgramInfo programs[ProgramCount]; int stencilIndex; - GlobalGLData() - : stencilIndex(1) - { } - } globalGLData; + SharedGLData(GLContext glContext) : stencilIndex(1) + { + glContextDataMap().add(glContext, this); + initializeShaders(); + } + + ~SharedGLData() + { + for (int i = SimpleProgram; i < ProgramCount; ++i) + deleteShaderProgram(ShaderProgramIndex(i)); + + GLContextDataMap::const_iterator end = glContextDataMap().end(); + GLContextDataMap::iterator it; + for (it = glContextDataMap().begin(); it != end; ++it) { + if (it->second == this) + break; + } + + ASSERT(it != end); + glContextDataMap().remove(it); + } + + }; struct DirectlyCompositedImageRepository { struct Entry { @@ -211,17 +314,22 @@ struct TextureMapperGLData { } } directlyCompositedImages; + SharedGLData& sharedGLData() const + { + return *(m_sharedGLData.get()); + } + TextureMapperGLData() - : currentProgram(TextureMapperGLData::GlobalGLData::NoProgram) + : currentProgram(SharedGLData::NoProgram) + , m_sharedGLData(TextureMapperGLData::SharedGLData::currentSharedGLData()) { } TransformationMatrix projectionMatrix; int currentProgram; int previousProgram; + RefPtr<SharedGLData> m_sharedGLData; }; -TextureMapperGLData::GlobalGLData TextureMapperGLData::globalGLData; - class BitmapTextureGL : public BitmapTexture { public: virtual void destroy(); @@ -289,11 +397,11 @@ private: }; #define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \ - if (TextureMapperGLData::globalGLData.getUniformLocation(TextureMapperGLData::globalGLData.prog##Program, TextureMapperGLData::globalGLData.var##Variable, #var) < 0) \ + if (getUniformLocation(prog##Program, var##Variable, #var) < 0) \ LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n"); #define TEXMAP_BUILD_SHADER(program) \ - TextureMapperGLData::globalGLData.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::globalGLData.program##Program); + createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, program##Program); TextureMapperGL::TextureMapperGL() : m_data(new TextureMapperGLData) @@ -301,12 +409,8 @@ TextureMapperGL::TextureMapperGL() { } -void TextureMapperGL::initializeShaders() +void TextureMapperGLData::SharedGLData::initializeShaders() { - static bool shadersCompiled = false; - if (shadersCompiled) - return; - shadersCompiled = true; #ifndef TEXMAP_OPENGL_ES_2 #define OES2_PRECISION_DEFINITIONS \ "#define lowp\n#define highp\n" @@ -322,6 +426,9 @@ void TextureMapperGL::initializeShaders() OES2_FRAGMENT_SHADER_DEFAULT_PRECISION\ #src + if (!initializeOpenGLShims()) + return; + const char* fragmentShaderSourceOpacityAndMask = FRAGMENT_SHADER( uniform sampler2D SourceTexture, MaskTexture; @@ -426,7 +533,6 @@ void TextureMapperGL::beginPainting() glClear(GL_STENCIL_BUFFER_BIT); bindSurface(0); #endif - initializeShaders(); } void TextureMapperGL::endPainting() @@ -454,13 +560,13 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& void TextureMapperGL::drawTexture(uint32_t texture, bool opaque, const FloatSize& relativeSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, bool flip) { - TextureMapperGLData::GlobalGLData::ShaderProgramIndex program; + TextureMapperGLData::SharedGLData::ShaderProgramIndex program; if (maskTexture) - program = TextureMapperGLData::GlobalGLData::OpacityAndMaskProgram; + program = TextureMapperGLData::SharedGLData::OpacityAndMaskProgram; else - program = TextureMapperGLData::GlobalGLData::SimpleProgram; + program = TextureMapperGLData::SharedGLData::SimpleProgram; - const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program]; + const TextureMapperGLData::SharedGLData::ProgramInfo& programInfo = data().sharedGLData().programs[program]; GL_CMD(glUseProgram(programInfo.id)) data().currentProgram = program; GL_CMD(glEnableVertexAttribArray(programInfo.vertexAttrib)) @@ -487,10 +593,10 @@ void TextureMapperGL::drawTexture(uint32_t texture, bool opaque, const FloatSize 0, 0, 1, 0, 0, flip ? relativeSize.height() : 0, 0, 1}; - GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4)) - GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InSourceMatrixVariable], 1, GL_FALSE, m4src)) - GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::SourceTextureVariable], 0)) - GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::GlobalGLData::OpacityVariable], opacity)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InSourceMatrixVariable], 1, GL_FALSE, m4src)) + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::SharedGLData::SourceTextureVariable], 0)) + GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::SharedGLData::OpacityVariable], opacity)) if (maskTexture && maskTexture->isValid()) { const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture); @@ -500,8 +606,8 @@ void TextureMapperGL::drawTexture(uint32_t texture, bool opaque, const FloatSize 0, maskTextureGL->relativeSize().height(), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMaskMatrixVariable], 1, GL_FALSE, m4mask)); - GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::MaskTextureVariable], 1)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMaskMatrixVariable], 1, GL_FALSE, m4mask)); + GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::SharedGLData::MaskTextureVariable], 1)) GL_CMD(glActiveTexture(GL_TEXTURE0)) } @@ -670,7 +776,7 @@ static inline TransformationMatrix createProjectionMatrix(const IntSize& size, b void BitmapTextureGL::bind() { - int& stencilIndex = TextureMapperGLData::globalGLData.stencilIndex; + int& stencilIndex = m_textureMapper->data().sharedGLData().stencilIndex; if (m_surfaceNeedsReset || !m_fbo) { if (!m_fbo) GL_CMD(glGenFramebuffers(1, &m_fbo)) @@ -743,7 +849,7 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) if (!surface) { GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0)) data().projectionMatrix = createProjectionMatrix(viewportSize(), true).multiply(transform()); - GL_CMD(glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1)) + GL_CMD(glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1)) GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)) GL_CMD(glViewport(0, 0, viewportSize().width(), viewportSize().height())) return; @@ -754,8 +860,8 @@ void TextureMapperGL::bindSurface(BitmapTexture *surfacePointer) void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect) { - TextureMapperGLData::GlobalGLData::ShaderProgramIndex program = TextureMapperGLData::GlobalGLData::ClipProgram; - const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program]; + TextureMapperGLData::SharedGLData::ShaderProgramIndex program = TextureMapperGLData::SharedGLData::ClipProgram; + const TextureMapperGLData::SharedGLData::ProgramInfo& programInfo = data().sharedGLData().programs[program]; GL_CMD(glUseProgram(programInfo.id)) GL_CMD(glEnableVertexAttribArray(programInfo.vertexAttrib)) const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1}; @@ -775,9 +881,9 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44() }; - int& stencilIndex = data().globalGLData.stencilIndex; + int& stencilIndex = data().sharedGLData().stencilIndex; - GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4)) + GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMatrixVariable], 1, GL_FALSE, m4)) GL_CMD(glEnable(GL_STENCIL_TEST)) GL_CMD(glStencilFunc(GL_NEVER, stencilIndex, stencilIndex)) GL_CMD(glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)) @@ -791,8 +897,8 @@ void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, con void TextureMapperGL::endClip() { - data().globalGLData.stencilIndex >>= 1; - glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1); + data().sharedGLData().stencilIndex >>= 1; + glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1); } PassRefPtr<BitmapTexture> TextureMapperGL::createTexture() diff --git a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h index 6f4c29d80..dd2e1a7c9 100644 --- a/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h +++ b/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h @@ -55,7 +55,6 @@ public: virtual bool isOpenGLBacked() const { return true; } private: - void initializeShaders(); inline TextureMapperGLData& data() { return *m_data; } TextureMapperGLData* m_data; GraphicsContext* m_context; diff --git a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp index d6428d98e..ee8ee0f74 100644 --- a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp +++ b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp @@ -160,9 +160,4 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const return width; } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp index 4ff23be1c..e95b8c5ea 100644 --- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp @@ -189,9 +189,4 @@ void SimpleFontData::platformDestroy() { } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 9135ff4e0..db343615f 100644 --- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -440,7 +440,17 @@ static void setPathFromConvexPoints(SkPath* path, size_t numPoints, const FloatP path->lineTo(WebCoreFloatToSkScalar(points[i].x()), WebCoreFloatToSkScalar(points[i].y())); } - path->setIsConvex(true); + + /* The code used to just blindly call this + path->setIsConvex(true); + But webkit can sometimes send us non-convex 4-point values, so we mark the path's + convexity as unknown, so it will get computed by skia at draw time. + See crbug.com 108605 + */ + SkPath::Convexity convexity = SkPath::kConvex_Convexity; + if (numPoints == 4) + convexity = SkPath::kUnknown_Convexity; + path->setConvexity(convexity); } void GraphicsContext::drawConvexPolygon(size_t numPoints, diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index 37d459d16..f96c5690d 100644 --- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -93,6 +93,13 @@ static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* d return canvas; } +static SkCanvas* createNonPlatformCanvas(const IntSize& size) +{ + SkCanvas* canvas = new SkCanvas(); + canvas->setDevice(new SkDevice(SkBitmap::kARGB_8888_Config, size.width(), size.height()))->unref(); + return canvas; +} + ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode renderingMode, bool& success) : m_data(size) , m_size(size) @@ -101,6 +108,8 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode renderin if (renderingMode == Accelerated) canvas = adoptPtr(createAcceleratedCanvas(size, &m_data)); + else if (renderingMode == UnacceleratedNonPlatformBuffer) + canvas = adoptPtr(createNonPlatformCanvas(size)); if (!canvas) canvas = adoptPtr(skia::TryCreateBitmapCanvas(size.width(), size.height(), false)); diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp index 7c8aea070..0ba6d070e 100644 --- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp @@ -197,7 +197,7 @@ static FloatPoint* convertPathPoints(FloatPoint dst[], const SkPoint src[], int void Path::apply(void* info, PathApplierFunction function) const { - SkPath::Iter iter(*m_path, false); + SkPath::RawIter iter(*m_path); SkPoint pts[4]; PathElement pathElement; FloatPoint pathPoints[3]; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp new file mode 100644 index 000000000..2622d21ca --- /dev/null +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.cpp @@ -0,0 +1,79 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TextureMapper.h" + +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + +namespace WebCore { + +PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& size) +{ + if (m_texturePool.isEmpty()) { + RefPtr<BitmapTexture> selectedTexture = createTexture(); + selectedTexture->reset(size, false); + selectedTexture->lock(); + return selectedTexture; + } + + size_t index = 0; + RefPtr<BitmapTexture> selectedTexture = m_texturePool[0]; + + for (size_t i = 1; i < m_texturePool.size(); ++i) { + RefPtr<BitmapTexture> texture = m_texturePool[i]; + + IntSize textureSize = texture->size(); + IntSize selectedTextureSize = selectedTexture->size(); + + // We prefer to pick a texture that's equal or larger than the requested size. + if (textureSize.width() < size.width() || textureSize.height() < size.height()) + continue; + + // We select the new texture if the currently selected texture is smaller than the + // required size, and the new texture has a smaller area. + int textureArea = textureSize.width() * textureSize.height(); + int selectedTextureArea = selectedTextureSize.width() * selectedTextureSize.height(); + bool selectedTextureFitsSize = + selectedTextureSize.width() >= size.width() + && selectedTextureSize.height() >= size.height(); + + if (selectedTextureFitsSize && selectedTextureArea <= textureArea) + continue; + + selectedTexture = texture; + index = i; + } + + m_texturePool.remove(index); + selectedTexture->reset(size, false); + selectedTexture->lock(); + return selectedTexture; +} + +void TextureMapper::releaseTextureToPool(BitmapTexture* texture) +{ + if (!texture) + return; + m_texturePool.append(texture); + texture->unlock(); +} + +} +#endif diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapper.h b/Source/WebCore/platform/graphics/texmap/TextureMapper.h index 27058aaca..d81333daa 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapper.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapper.h @@ -126,6 +126,9 @@ public: virtual void beginPainting() { } virtual void endPainting() { } + virtual void releaseTextureToPool(BitmapTexture* surface); + virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&); + protected: TextureMapper() @@ -138,6 +141,7 @@ private: TextDrawingModeFlags m_textDrawingMode; TransformationMatrix m_transform; IntSize m_viewportSize; + Vector<RefPtr<BitmapTexture> > m_texturePool; }; }; diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp index 9157e23ac..15dff5aeb 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp @@ -31,40 +31,6 @@ namespace { namespace WebCore { -class TextureMapperSurfaceManager { -public: - TextureMapper* textureMapper; - Vector<RefPtr<BitmapTexture> > surfaces; - IntSize viewportSize; - - PassRefPtr<BitmapTexture> getIntermediateSurface() - { - IntSize newViewportSize = textureMapper->viewportSize(); - if (newViewportSize != viewportSize) { - viewportSize = newViewportSize; - surfaces.clear(); - } - if (surfaces.isEmpty()) { - RefPtr<BitmapTexture> newSurface = textureMapper->createTexture(); - newSurface->reset(viewportSize, false); - return newSurface.get(); - } - RefPtr<BitmapTexture> surface = surfaces.last(); - surface->reset(viewportSize, false); - surfaces.removeLast(); - surface->lock(); - return surface.get(); - } - - void releaseIntermediateSurface(BitmapTexture* surface) - { - if (!surface) - return; - surfaces.append(surface); - surface->unlock(); - } -}; - TextureMapperNode* toTextureMapperNode(GraphicsLayer* layer) { return layer ? toGraphicsLayerTextureMapper(layer)->node() : 0; @@ -346,11 +312,7 @@ void TextureMapperNode::paint() if (m_size.isEmpty()) return; - if (!m_surfaceManager) - m_surfaceManager = new TextureMapperSurfaceManager; - m_surfaceManager->textureMapper = m_textureMapper; TextureMapperPaintOptions opt; - opt.surfaceManager = m_surfaceManager; opt.textureMapper = m_textureMapper; opt.textureMapper->bindSurface(0); paintRecursive(opt); @@ -496,7 +458,7 @@ bool TextureMapperNode::paintReflection(const TextureMapperPaintOptions& options // The mask has to be adjusted to target coordinates. if (maskTexture) { - maskSurface = options.surfaceManager->getIntermediateSurface(); + maskSurface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); options.textureMapper->bindSurface(maskSurface.get()); options.textureMapper->drawTexture(*maskTexture.get(), entireRect(), m_transforms.target, 1, 0); maskTexture = maskSurface; @@ -504,7 +466,7 @@ bool TextureMapperNode::paintReflection(const TextureMapperPaintOptions& options // The replica's mask has to be adjusted to target coordinates. if (replicaMaskTexture) { - replicaMaskSurface = options.surfaceManager->getIntermediateSurface(); + replicaMaskSurface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); options.textureMapper->bindSurface(replicaMaskSurface.get()); options.textureMapper->drawTexture(*replicaMaskTexture.get(), entireRect(), m_transforms.target, 1, 0); replicaMaskTexture = replicaMaskSurface; @@ -512,21 +474,21 @@ bool TextureMapperNode::paintReflection(const TextureMapperPaintOptions& options // We might need to apply the mask of the content layer before we draw the reflection, as there might be yet another mask for the reflection itself. if (useIntermediateBufferForMask) { - RefPtr<BitmapTexture> maskSurface = options.surfaceManager->getIntermediateSurface(); + RefPtr<BitmapTexture> maskSurface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); options.textureMapper->bindSurface(maskSurface.get()); options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), 1, maskTexture.get()); - options.surfaceManager->releaseIntermediateSurface(surface.get()); + options.textureMapper->releaseTextureToPool(surface.get()); surface = maskSurface; maskTexture.clear(); } // We blend the layer and its replica in an intermediate buffer before blending into the target surface. if (useIntermediateBufferForReplica) { - RefPtr<BitmapTexture> replicaSurface = options.surfaceManager->getIntermediateSurface(); + RefPtr<BitmapTexture> replicaSurface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); options.textureMapper->bindSurface(replicaSurface.get()); options.textureMapper->drawTexture(*surface.get(), viewportRect, m_transforms.replica, m_state.replicaLayer->m_opacity, replicaMaskTexture.get()); options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), 1, maskTexture.get()); - options.surfaceManager->releaseIntermediateSurface(surface.get()); + options.textureMapper->releaseTextureToPool(surface.get()); surface = replicaSurface; } @@ -539,8 +501,8 @@ bool TextureMapperNode::paintReflection(const TextureMapperPaintOptions& options // Draw the original. options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), options.opacity, maskTexture.get()); - options.surfaceManager->releaseIntermediateSurface(maskSurface.get()); - options.surfaceManager->releaseIntermediateSurface(replicaMaskSurface.get()); + options.textureMapper->releaseTextureToPool(maskSurface.get()); + options.textureMapper->releaseTextureToPool(replicaMaskSurface.get()); return true; } @@ -570,12 +532,12 @@ void TextureMapperNode::paintRecursive(TextureMapperPaintOptions options) // The mask has to be adjusted to target coordinates. if (m_state.maskLayer) { - maskSurface = options.surfaceManager->getIntermediateSurface(); + maskSurface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); options.textureMapper->bindSurface(maskSurface.get()); options.textureMapper->drawTexture(*m_state.maskLayer->texture(), entireRect(), m_transforms.target, 1.0, 0); } - surface = options.surfaceManager->getIntermediateSurface(); + surface = options.textureMapper->acquireTextureFromPool(options.textureMapper->viewportSize()); optionsForDescendants.surface = surface.get(); options.isSurface = true; optionsForDescendants.opacity = 1; @@ -588,8 +550,8 @@ void TextureMapperNode::paintRecursive(TextureMapperPaintOptions options) options.textureMapper->drawTexture(*surface.get(), viewportRect, TransformationMatrix(), options.opacity, 0); } - options.surfaceManager->releaseIntermediateSurface(surface.get()); - options.surfaceManager->releaseIntermediateSurface(maskSurface.get()); + options.textureMapper->releaseTextureToPool(surface.get()); + options.textureMapper->releaseTextureToPool(maskSurface.get()); } TextureMapperNode::~TextureMapperNode() diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h index fc479bac6..b40cd5d38 100644 --- a/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h +++ b/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h @@ -39,17 +39,20 @@ namespace WebCore { class TextureMapperPlatformLayer; class TextureMapperNode; class GraphicsLayerTextureMapper; -class TextureMapperSurfaceManager; class TextureMapperPaintOptions { public: BitmapTexture* surface; TextureMapper* textureMapper; - TextureMapperSurfaceManager* surfaceManager; float opacity; bool isSurface; - TextureMapperPaintOptions() : surface(0), textureMapper(0), opacity(1.0), isSurface(false) { } + TextureMapperPaintOptions() + : surface(0) + , textureMapper(0) + , opacity(1) + , isSurface(false) + { } }; class TextureMapperAnimation : public RefCounted<TextureMapperAnimation> { @@ -135,7 +138,11 @@ public: }; TextureMapperNode() - : m_parent(0), m_effectTarget(0), m_opacity(1.0), m_surfaceManager(0), m_textureMapper(0) { } + : m_parent(0) + , m_effectTarget(0) + , m_opacity(1) + , m_textureMapper(0) + { } virtual ~TextureMapperNode(); @@ -317,7 +324,6 @@ private: }; State m_state; - TextureMapperSurfaceManager* m_surfaceManager; TextureMapper* m_textureMapper; Vector<RefPtr<TextureMapperAnimation> > m_animations; diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h index 4d6c7da9a..d3970da29 100644 --- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h +++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h @@ -63,6 +63,10 @@ public: AffineTransform(); AffineTransform(double a, double b, double c, double d, double e, double f); +#if USE(CG) + AffineTransform(const CGAffineTransform&); +#endif + void setMatrix(double a, double b, double c, double d, double e, double f); void map(double x, double y, double& x2, double& y2) const; diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp index a49abe2ef..de6687f5c 100644 --- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp +++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp @@ -282,9 +282,4 @@ SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const return m_scriptFontProperties; } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } diff --git a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp index 1ba669074..e3b842463 100644 --- a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp @@ -180,9 +180,4 @@ void SimpleFontData::platformCharWidthInit() m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72; } -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp index d98ecbd60..cb7fb3d7a 100644 --- a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp +++ b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp @@ -194,9 +194,4 @@ float SimpleFontData::widthForGDIGlyph(Glyph glyph) const } #endif -void SimpleFontData::updateGlyphWithVariationSelector(UChar32 character, UChar32 selector, Glyph& glyph) const -{ - // FIXME: Implement. -} - } diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 6df47339f..0cbdd0453 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -75,7 +75,11 @@ extern "C" { #if defined(JCS_EXTENSIONS) && ASSUME_LITTLE_ENDIAN #define TURBO_JPEG_RGB_SWIZZLE +#if USE(SKIA) && (!SK_R32_SHIFT && SK_G32_SHIFT == 8 && SK_B32_SHIFT == 16) +inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_RGBX; } +#else inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_BGRX; } +#endif inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == rgbOutputColorSpace(); } #else inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_RGB; } diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.h b/Source/WebCore/platform/mac/ScrollAnimatorMac.h index 29c13aa25..94383ca5e 100644 --- a/Source/WebCore/platform/mac/ScrollAnimatorMac.h +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.h @@ -123,13 +123,16 @@ private: FloatPoint adjustScrollPositionIfNecessary(const FloatPoint&) const; void immediateScrollTo(const FloatPoint&); - void immediateScrollBy(const FloatSize&); #if ENABLE(RUBBER_BANDING) /// ScrollElasticityControllerClient member functions. virtual IntSize stretchAmount() OVERRIDE; virtual bool pinnedInDirection(const FloatSize&) OVERRIDE; + virtual bool canScrollHorizontally() OVERRIDE; + virtual bool canScrollVertically() OVERRIDE; + virtual WebCore::IntPoint absoluteScrollPosition() OVERRIDE; virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) OVERRIDE; + virtual void immediateScrollBy(const FloatSize&) OVERRIDE; virtual void startSnapRubberbandTimer() OVERRIDE; virtual void stopSnapRubberbandTimer() OVERRIDE; @@ -138,7 +141,7 @@ private: bool pinnedInDirection(float deltaX, float deltaY); void snapRubberBand(); void snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*); - void smoothScrollWithEvent(const PlatformWheelEvent&); + bool smoothScrollWithEvent(const PlatformWheelEvent&); void beginScrollGesture(); void endScrollGesture(); diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm index 884a87d8b..4011f33e8 100644 --- a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm @@ -82,7 +82,7 @@ static NSTimeInterval systemUptime() return [[NSProcessInfo processInfo] systemUptime]; // Get how long system has been up. Found by looking getting "boottime" from the kernel. - static struct timeval boottime = {}; + static struct timeval boottime = {0, 0}; if (!boottime.tv_sec) { int mib[2] = {CTL_KERN, KERN_BOOTTIME}; size_t size = sizeof(boottime); @@ -690,19 +690,6 @@ void ScrollAnimatorMac::immediateScrollTo(const FloatPoint& newPosition) notifyPositionChanged(); } -void ScrollAnimatorMac::immediateScrollBy(const FloatSize& delta) -{ - float newPosX = adjustScrollXPositionIfNecessary(m_currentPosX + delta.width()); - float newPosY = adjustScrollYPositionIfNecessary(m_currentPosY + delta.height()); - - if (newPosX == m_currentPosX && newPosY == m_currentPosY) - return; - - m_currentPosX = newPosX; - m_currentPosY = newPosY; - notifyPositionChanged(); -} - void ScrollAnimatorMac::immediateScrollToPointForScrollAnimation(const FloatPoint& newPosition) { ASSERT(m_scrollAnimationHelper); @@ -1008,17 +995,7 @@ bool ScrollAnimatorMac::handleWheelEvent(const PlatformWheelEvent& wheelEvent) } } - bool isMomentumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone); - if (m_scrollElasticityController.m_ignoreMomentumScrolls && (isMomentumScrollEvent || m_scrollElasticityController.m_snapRubberbandTimerIsActive)) { - if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded) { - m_scrollElasticityController.m_ignoreMomentumScrolls = false; - return true; - } - return false; - } - - smoothScrollWithEvent(wheelEvent); - return true; + return smoothScrollWithEvent(wheelEvent); } void ScrollAnimatorMac::handleGestureEvent(const PlatformGestureEvent& gestureEvent) @@ -1065,6 +1042,27 @@ bool ScrollAnimatorMac::pinnedInDirection(const FloatSize& direction) return pinnedInDirection(direction.width(), direction.height()); } +bool ScrollAnimatorMac::canScrollHorizontally() +{ + Scrollbar* scrollbar = m_scrollableArea->horizontalScrollbar(); + if (!scrollbar) + return false; + return scrollbar->enabled(); +} + +bool ScrollAnimatorMac::canScrollVertically() +{ + Scrollbar* scrollbar = m_scrollableArea->verticalScrollbar(); + if (!scrollbar) + return false; + return scrollbar->enabled(); +} + +IntPoint ScrollAnimatorMac::absoluteScrollPosition() +{ + return m_scrollableArea->visibleContentRect().location() + m_scrollableArea->scrollOrigin(); +} + void ScrollAnimatorMac::immediateScrollByWithoutContentEdgeConstraints(const FloatSize& delta) { m_scrollableArea->setConstrainsScrollingToContentEdge(false); @@ -1072,6 +1070,19 @@ void ScrollAnimatorMac::immediateScrollByWithoutContentEdgeConstraints(const Flo m_scrollableArea->setConstrainsScrollingToContentEdge(true); } +void ScrollAnimatorMac::immediateScrollBy(const FloatSize& delta) +{ + float newPosX = adjustScrollXPositionIfNecessary(m_currentPosX + delta.width()); + float newPosY = adjustScrollYPositionIfNecessary(m_currentPosY + delta.height()); + + if (newPosX == m_currentPosX && newPosY == m_currentPosY) + return; + + m_currentPosX = newPosX; + m_currentPosY = newPosY; + notifyPositionChanged(); +} + void ScrollAnimatorMac::startSnapRubberbandTimer() { m_snapRubberBandTimer.startRepeating(1.0 / 60.0); @@ -1118,8 +1129,17 @@ bool ScrollAnimatorMac::allowsHorizontalStretching() const return false; } -void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEvent) +bool ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEvent) { + bool isMomentumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone); + if (m_scrollElasticityController.m_ignoreMomentumScrolls && (isMomentumScrollEvent || m_scrollElasticityController.m_snapRubberbandTimerIsActive)) { + if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded) { + m_scrollElasticityController.m_ignoreMomentumScrolls = false; + return true; + } + return false; + } + m_haveScrolledSincePageLoad = true; float deltaX = m_scrollElasticityController.m_overflowScrollDelta.width(); @@ -1144,7 +1164,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve bool isHorizontallyStretched = false; bool shouldStretch = false; - IntSize stretchAmount = m_scrollableArea->overhangAmount(); + IntSize stretchAmount = m_scrollElasticityController.m_client->stretchAmount(); isHorizontallyStretched = stretchAmount.width(); isVerticallyStretched = stretchAmount.height(); @@ -1207,11 +1227,11 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve if (!(shouldStretch || isVerticallyStretched || isHorizontallyStretched)) { if (deltaY != 0) { deltaY *= scrollWheelMultiplier(); - immediateScrollBy(FloatSize(0, deltaY)); + m_scrollElasticityController.m_client->immediateScrollBy(FloatSize(0, deltaY)); } if (deltaX != 0) { deltaX *= scrollWheelMultiplier(); - immediateScrollBy(FloatSize(deltaX, 0)); + m_scrollElasticityController.m_client->immediateScrollBy(FloatSize(deltaX, 0)); } } else { if (!allowsHorizontalStretching()) { @@ -1220,7 +1240,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve } else if ((deltaX != 0) && !isHorizontallyStretched && !pinnedInDirection(deltaX, 0)) { deltaX *= scrollWheelMultiplier(); - immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0)); + m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0)); deltaX = 0; } @@ -1230,11 +1250,11 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve } else if ((deltaY != 0) && !isVerticallyStretched && !pinnedInDirection(0, deltaY)) { deltaY *= scrollWheelMultiplier(); - immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY)); + m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY)); deltaY = 0; } - IntSize stretchAmount = m_scrollableArea->overhangAmount(); + IntSize stretchAmount = m_scrollElasticityController.m_client->stretchAmount(); if (m_scrollElasticityController.m_momentumScrollInProgress) { if ((pinnedInDirection(eventCoalescedDeltaX, eventCoalescedDeltaY) || (fabsf(eventCoalescedDeltaX) + fabsf(eventCoalescedDeltaY) <= 0)) && m_scrollElasticityController.m_lastMomentumScrollTimestamp) { @@ -1249,7 +1269,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve FloatSize dampedDelta(ceilf(elasticDeltaForReboundDelta(m_scrollElasticityController.m_stretchScrollForce.width())), ceilf(elasticDeltaForReboundDelta(m_scrollElasticityController.m_stretchScrollForce.height()))); - immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount); + m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount); } } @@ -1258,6 +1278,8 @@ void ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEve m_scrollElasticityController.m_ignoreMomentumScrolls = false; m_scrollElasticityController.m_lastMomentumScrollTimestamp = 0; } + + return true; } void ScrollAnimatorMac::beginScrollGesture() @@ -1296,7 +1318,7 @@ void ScrollAnimatorMac::snapRubberBand() m_scrollElasticityController.m_origOrigin = FloatPoint(); m_scrollElasticityController.m_origVelocity = FloatSize(); - m_snapRubberBandTimer.startRepeating(1.0/60.0); + m_scrollElasticityController.m_client->startSnapRubberbandTimer(); m_scrollElasticityController.m_snapRubberbandTimerIsActive = true; } @@ -1320,9 +1342,9 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) CFTimeInterval timeDelta = [NSDate timeIntervalSinceReferenceDate] - m_scrollElasticityController.m_startTime; if (m_scrollElasticityController.m_startStretch == FloatSize()) { - m_scrollElasticityController.m_startStretch = m_scrollableArea->overhangAmount(); - if (m_scrollElasticityController.m_startStretch == FloatSize()) { - m_snapRubberBandTimer.stop(); + m_scrollElasticityController.m_startStretch = m_scrollElasticityController.m_client->stretchAmount(); + if (m_scrollElasticityController.m_startStretch == FloatSize()) { + m_scrollElasticityController.m_client->stopSnapRubberbandTimer(); m_scrollElasticityController.m_stretchScrollForce = FloatSize(); m_scrollElasticityController.m_startTime = 0; @@ -1334,7 +1356,7 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) return; } - m_scrollElasticityController.m_origOrigin = (m_scrollableArea->visibleContentRect().location() + m_scrollableArea->scrollOrigin()) - m_scrollElasticityController.m_startStretch; + m_scrollElasticityController.m_origOrigin = m_scrollElasticityController.m_client->absoluteScrollPosition() - m_scrollElasticityController.m_startStretch; m_scrollElasticityController.m_origVelocity = m_scrollElasticityController.m_momentumVelocity; // Just like normal scrolling, prefer vertical rubberbanding @@ -1342,13 +1364,11 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) m_scrollElasticityController.m_origVelocity.setWidth(0); // Don't rubber-band horizontally if it's not possible to scroll horizontally - Scrollbar* hScroller = m_scrollableArea->horizontalScrollbar(); - if (!hScroller || !hScroller->enabled()) + if (!m_scrollElasticityController.m_client->canScrollHorizontally()) m_scrollElasticityController.m_origVelocity.setWidth(0); - // Don't rubber-band vertically if it's not possible to scroll horizontally - Scrollbar* vScroller = m_scrollableArea->verticalScrollbar(); - if (!vScroller || !vScroller->enabled()) + // Don't rubber-band vertically if it's not possible to scroll vertically + if (!m_scrollElasticityController.m_client->canScrollVertically()) m_scrollElasticityController.m_origVelocity.setHeight(0); } @@ -1358,16 +1378,16 @@ void ScrollAnimatorMac::snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*) if (fabs(delta.x()) >= 1 || fabs(delta.y()) >= 1) { FloatPoint newOrigin = m_scrollElasticityController.m_origOrigin + delta; - immediateScrollByWithoutContentEdgeConstraints(FloatSize(delta.x(), delta.y()) - m_scrollableArea->overhangAmount()); + m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(delta.x(), delta.y()) - m_scrollElasticityController.m_client->stretchAmount()); - FloatSize newStretch = m_scrollableArea->overhangAmount(); + FloatSize newStretch = m_scrollElasticityController.m_client->stretchAmount(); m_scrollElasticityController.m_stretchScrollForce.setWidth(reboundDeltaForElasticDelta(newStretch.width())); m_scrollElasticityController.m_stretchScrollForce.setHeight(reboundDeltaForElasticDelta(newStretch.height())); } else { immediateScrollTo(m_scrollElasticityController.m_origOrigin); - m_snapRubberBandTimer.stop(); + m_scrollElasticityController.m_client->stopSnapRubberbandTimer(); m_scrollElasticityController.m_stretchScrollForce = FloatSize(); m_scrollElasticityController.m_startTime = 0; diff --git a/Source/WebCore/platform/mac/ScrollElasticityController.h b/Source/WebCore/platform/mac/ScrollElasticityController.h index f1b89b28d..066184473 100644 --- a/Source/WebCore/platform/mac/ScrollElasticityController.h +++ b/Source/WebCore/platform/mac/ScrollElasticityController.h @@ -41,6 +41,13 @@ protected: public: virtual IntSize stretchAmount() = 0; virtual bool pinnedInDirection(const FloatSize&) = 0; + virtual bool canScrollHorizontally() = 0; + virtual bool canScrollVertically() = 0; + + // Return the absolute scroll position, not relative to the scroll origin. + virtual WebCore::IntPoint absoluteScrollPosition() = 0; + + virtual void immediateScrollBy(const FloatSize&) = 0; virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0; virtual void startSnapRubberbandTimer() = 0; virtual void stopSnapRubberbandTimer() = 0; @@ -55,13 +62,13 @@ public: void beginScrollGesture(); private: - ScrollElasticityControllerClient* m_client; - void stopSnapRubberbandTimer(); // FIXME: These member variables should be private. They are currently public as a stop-gap measure, while // the rubber-band related code from ScrollAnimatorMac is being moved over. public: + ScrollElasticityControllerClient* m_client; + bool m_inScrollGesture; bool m_momentumScrollInProgress; bool m_ignoreMomentumScrolls; diff --git a/Source/WebCore/platform/mock/ScrollbarThemeMock.cpp b/Source/WebCore/platform/mock/ScrollbarThemeMock.cpp index 70707d480..5d2bc3ec0 100644 --- a/Source/WebCore/platform/mock/ScrollbarThemeMock.cpp +++ b/Source/WebCore/platform/mock/ScrollbarThemeMock.cpp @@ -42,14 +42,15 @@ int ScrollbarThemeMock::scrollbarThickness(ScrollbarControlSize controlSize) return cScrollbarThickness[controlSize]; } -void ScrollbarThemeMock::paintTrackBackground(GraphicsContext* context, Scrollbar*, const IntRect& trackRect) +void ScrollbarThemeMock::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& trackRect) { - context->fillRect(trackRect, Color::lightGray, ColorSpaceDeviceRGB); + context->fillRect(trackRect, scrollbar->enabled() ? Color::lightGray : Color(0xFFE0E0E0), ColorSpaceDeviceRGB); } -void ScrollbarThemeMock::paintThumb(GraphicsContext* context, Scrollbar*, const IntRect& thumbRect) +void ScrollbarThemeMock::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& thumbRect) { - context->fillRect(thumbRect, Color::darkGray, ColorSpaceDeviceRGB); + if (scrollbar->enabled()) + context->fillRect(thumbRect, Color::darkGray, ColorSpaceDeviceRGB); } } diff --git a/Source/WebCore/platform/network/blackberry/ResourceHandleBlackBerry.cpp b/Source/WebCore/platform/network/blackberry/ResourceHandleBlackBerry.cpp index 0820348b8..fe0df4e1b 100644 --- a/Source/WebCore/platform/network/blackberry/ResourceHandleBlackBerry.cpp +++ b/Source/WebCore/platform/network/blackberry/ResourceHandleBlackBerry.cpp @@ -22,6 +22,7 @@ #include "EventLoop.h" #include "Frame.h" #include "FrameLoaderClientBlackBerry.h" +#include "FrameNetworkingContextBlackBerry.h" #include "NetworkManager.h" #include "NotImplemented.h" #include "Page.h" @@ -112,7 +113,7 @@ bool ResourceHandle::start(NetworkingContext* context) return false; // FIXME: clean up use of Frame now that we have NetworkingContext (see RIM Bug #1515) - Frame* frame = context->wrappedFrame(); + Frame* frame = static_cast<FrameNetworkingContextBlackBerry*>(context)->frame(); if (!frame || !frame->loader() || !frame->loader()->client() || !client()) return false; int playerId = static_cast<FrameLoaderClientBlackBerry*>(frame->loader()->client())->playerId(); @@ -144,7 +145,7 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const } // FIXME: clean up use of Frame now that we have NetworkingContext (see RIM Bug #1515) - Frame* frame = context->wrappedFrame(); + Frame* frame = static_cast<FrameNetworkingContextBlackBerry*>(context)->frame(); if (!frame || !frame->loader() || !frame->loader()->client() || !frame->page()) { ASSERT(false && "loadResourceSynchronously called without a frame or frame client"); return; diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp index 7e1edc05f..3ec325444 100644 --- a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp +++ b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp @@ -333,11 +333,20 @@ static CFCachedURLResponseRef willCacheResponse(CFURLConnectionRef, CFCachedURLR handle->client()->willCacheResponse(handle, policy); if (static_cast<CFURLCacheStoragePolicy>(policy) != CFCachedURLResponseGetStoragePolicy(cachedResponse)) { +#if HAVE(NETWORK_CFDATA_ARRAY_CALLBACK) + RetainPtr<CFArrayRef> receiverData(AdoptCF, CFCachedURLResponseCopyReceiverDataArray(cachedResponse)); + cachedResponse = CFCachedURLResponseCreateWithDataArray(kCFAllocatorDefault, + CFCachedURLResponseGetWrappedResponse(cachedResponse), + receiverData.get(), + CFCachedURLResponseGetUserInfo(cachedResponse), + static_cast<CFURLCacheStoragePolicy>(policy)); +#else cachedResponse = CFCachedURLResponseCreateWithUserInfo(kCFAllocatorDefault, CFCachedURLResponseGetWrappedResponse(cachedResponse), CFCachedURLResponseGetReceiverData(cachedResponse), CFCachedURLResponseGetUserInfo(cachedResponse), static_cast<CFURLCacheStoragePolicy>(policy)); +#endif } else CFRetain(cachedResponse); @@ -1001,7 +1010,7 @@ void ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(const String privateBrowsingStorageSessionIdentifierBase() = identifier; } -#if PLATFORM(WIN) +#if PLATFORM(WIN) || USE(CFNETWORK) String ResourceHandle::privateBrowsingStorageSessionIdentifierDefaultBase() { |