diff options
Diffstat (limited to 'Source/WebCore/platform/graphics')
169 files changed, 4552 insertions, 2199 deletions
diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp index 1148aa6..6027f34 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.cpp +++ b/Source/WebCore/platform/graphics/BitmapImage.cpp @@ -60,6 +60,7 @@ BitmapImage::BitmapImage(ImageObserver* observer) , m_sizeAvailable(false) , m_hasUniformFrameSize(true) , m_decodedSize(0) + , m_decodedPropertiesSize(0) , m_haveFrameCount(false) , m_frameCount(0) { @@ -104,8 +105,12 @@ void BitmapImage::destroyMetadataAndNotify(int framesCleared) m_isSolidColor = false; invalidatePlatformData(); - const int deltaBytes = framesCleared * -frameBytes(m_size); + int deltaBytes = framesCleared * -frameBytes(m_size); m_decodedSize += deltaBytes; + if (framesCleared > 0) { + deltaBytes -= m_decodedPropertiesSize; + m_decodedPropertiesSize = 0; + } if (deltaBytes && imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); } @@ -132,18 +137,41 @@ void BitmapImage::cacheFrame(size_t index) if (frameSize != m_size) m_hasUniformFrameSize = false; if (m_frames[index].m_frame) { - const int deltaBytes = frameBytes(frameSize); + int deltaBytes = frameBytes(frameSize); m_decodedSize += deltaBytes; + // The fully-decoded frame will subsume the partially decoded data used + // to determine image properties. + deltaBytes -= m_decodedPropertiesSize; + m_decodedPropertiesSize = 0; if (imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); } } +void BitmapImage::didDecodeProperties() const +{ + if (m_decodedSize) + return; + size_t updatedSize = m_source.bytesDecodedToDetermineProperties(); + if (m_decodedPropertiesSize == updatedSize) + return; + int deltaBytes = updatedSize - m_decodedPropertiesSize; +#ifndef NDEBUG + bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0; + bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0; + ASSERT(!overflow && !underflow); +#endif + m_decodedPropertiesSize = updatedSize; + if (imageObserver()) + imageObserver()->decodedSizeChanged(this, deltaBytes); +} + IntSize BitmapImage::size() const { if (m_sizeAvailable && !m_haveSize) { m_size = m_source.size(); m_haveSize = true; + didDecodeProperties(); } return m_size; } @@ -152,12 +180,16 @@ IntSize BitmapImage::currentFrameSize() const { if (!m_currentFrame || m_hasUniformFrameSize) return size(); - return m_source.frameSizeAtIndex(m_currentFrame); + IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame); + didDecodeProperties(); + return frameSize; } bool BitmapImage::getHotSpot(IntPoint& hotSpot) const { - return m_source.getHotSpot(hotSpot); + bool result = m_source.getHotSpot(hotSpot); + didDecodeProperties(); + return result; } bool BitmapImage::dataChanged(bool allDataReceived) @@ -190,6 +222,7 @@ size_t BitmapImage::frameCount() if (!m_haveFrameCount) { m_haveFrameCount = true; m_frameCount = m_source.frameCount(); + didDecodeProperties(); } return m_frameCount; } @@ -200,6 +233,7 @@ bool BitmapImage::isSizeAvailable() return true; m_sizeAvailable = m_source.isSizeAvailable(); + didDecodeProperties(); return m_sizeAvailable; } @@ -256,6 +290,7 @@ int BitmapImage::repetitionCount(bool imageKnownToBeComplete) // decoder will default to cAnimationLoopOnce, and we'll try and read // the count again once the whole image is decoded. m_repetitionCount = m_source.repetitionCount(); + didDecodeProperties(); m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain; } return m_repetitionCount; diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h index 93fc464..14a3094 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.h +++ b/Source/WebCore/platform/graphics/BitmapImage.h @@ -215,6 +215,12 @@ protected: // Whether or not size is available yet. bool isSizeAvailable(); + // Called after asking the source for any information that may require + // decoding part of the image (e.g., the image size). We need to report + // the partially decoded data to our observer so it has an accurate + // account of the BitmapImage's memory usage. + void didDecodeProperties() const; + // Animation. int repetitionCount(bool imageKnownToBeComplete); // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded. bool shouldAnimate(); @@ -281,6 +287,7 @@ protected: mutable bool m_hasUniformFrameSize; unsigned m_decodedSize; // The current size of all decoded frames. + mutable unsigned m_decodedPropertiesSize; // The size of data decoded by the source to determine image properties (e.g. size, frame count, etc). mutable bool m_haveFrameCount; size_t m_frameCount; diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp index fa7346e..a1c5cd7 100644 --- a/Source/WebCore/platform/graphics/Color.cpp +++ b/Source/WebCore/platform/graphics/Color.cpp @@ -180,19 +180,52 @@ Color::Color(const char* name) } } +static inline void appendHexNumber(UChar* destination, uint8_t number) +{ + static const char hexDigits[17] = "0123456789abcdef"; + + destination[0] = hexDigits[number >> 4]; + destination[1] = hexDigits[number & 0xF]; +} + String Color::serialized() const { - if (alpha() == 0xFF) - return String::format("#%02x%02x%02x", red(), green(), blue()); + DEFINE_STATIC_LOCAL(const String, commaSpace, (", ")); + DEFINE_STATIC_LOCAL(const String, rgbaParen, ("rgba(")); + DEFINE_STATIC_LOCAL(const String, zeroPointZero, ("0.0")); + + if (!hasAlpha()) { + UChar* characters; + String result = String::createUninitialized(7, characters); + characters[0] = '#'; + appendHexNumber(characters + 1, red()); + appendHexNumber(characters + 3, green()); + appendHexNumber(characters + 5, blue()); + return result; + } + + Vector<UChar> result; + result.reserveInitialCapacity(28); + + append(result, rgbaParen); + appendNumber(result, red()); + append(result, commaSpace); + appendNumber(result, green()); + append(result, commaSpace); + appendNumber(result, blue()); + append(result, commaSpace); // Match Gecko ("0.0" for zero, 5 decimals for anything else) if (!alpha()) - return String::format("rgba(%u, %u, %u, 0.0)", red(), green(), blue()); + append(result, zeroPointZero); + else + append(result, String::format("%.5f", alpha() / 255.0f)); - return String::format("rgba(%u, %u, %u, %.5f)", red(), green(), blue(), alpha() / 255.0f); + result.append(')'); + return String::adopt(result); } -String Color::name() const +String Color::nameForRenderTreeAsText() const { if (alpha() < 0xFF) return String::format("#%02X%02X%02X%02X", red(), green(), blue(), alpha()); diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h index 2a03238..05d9554 100644 --- a/Source/WebCore/platform/graphics/Color.h +++ b/Source/WebCore/platform/graphics/Color.h @@ -96,7 +96,10 @@ public: // - http://www.whatwg.org/specs/web-apps/current-work/#serialization-of-a-color String serialized() const; - String name() const; + // Returns the color serialized as either #RRGGBB or #RRGGBBAA + // The latter format is not a valid CSS color, and should only be seen in DRT dumps. + String nameForRenderTreeAsText() const; + void setNamedColor(const String&); bool isValid() const { return m_valid; } diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h index 6d6efe5..5d5a5b7 100644 --- a/Source/WebCore/platform/graphics/Extensions3D.h +++ b/Source/WebCore/platform/graphics/Extensions3D.h @@ -26,6 +26,8 @@ #ifndef Extensions3D_h #define Extensions3D_h +#include "GraphicsTypes3D.h" + #include <wtf/text/WTFString.h> namespace WebCore { @@ -53,6 +55,7 @@ public: // GL_OES_texture_float // GL_OES_standard_derivatives // GL_OES_rgb8_rgba8 + // GL_OES_vertex_array_object // Takes full name of extension; for example, // "GL_EXT_texture_format_BGRA8888". @@ -92,6 +95,9 @@ public: // GL_OES_rgb8_rgba8 names RGB8_OES = 0x8051, RGBA8_OES = 0x8058, + + // GL_OES_vertex_array_object names + VERTEX_ARRAY_BINDING_OES = 0x85B5, }; // GL_ARB_robustness @@ -101,7 +107,13 @@ public: virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) = 0; // GL_ANGLE_framebuffer_multisample - virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) = 0; + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) = 0; + + // GL_OES_vertex_array_object + virtual Platform3DObject createVertexArrayOES() = 0; + virtual void deleteVertexArrayOES(Platform3DObject) = 0; + virtual GC3Dboolean isVertexArrayOES(Platform3DObject) = 0; + virtual void bindVertexArrayOES(Platform3DObject) = 0; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/FloatPoint.h b/Source/WebCore/platform/graphics/FloatPoint.h index 73a1bac..c4b2943 100644 --- a/Source/WebCore/platform/graphics/FloatPoint.h +++ b/Source/WebCore/platform/graphics/FloatPoint.h @@ -54,7 +54,7 @@ QT_END_NAMESPACE class BPoint; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkPoint; #endif @@ -130,7 +130,7 @@ public: operator BPoint() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) operator SkPoint() const; FloatPoint(const SkPoint&); #endif diff --git a/Source/WebCore/platform/graphics/FloatRect.h b/Source/WebCore/platform/graphics/FloatRect.h index 733f7cc..bd23476 100644 --- a/Source/WebCore/platform/graphics/FloatRect.h +++ b/Source/WebCore/platform/graphics/FloatRect.h @@ -55,7 +55,7 @@ class wxRect2DDouble; class BRect; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkRect; #endif @@ -163,7 +163,7 @@ public: operator BRect() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) FloatRect(const SkRect&); operator SkRect() const; #endif diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp index 6bdddfc..ee85e45 100644 --- a/Source/WebCore/platform/graphics/Font.cpp +++ b/Source/WebCore/platform/graphics/Font.cpp @@ -39,17 +39,6 @@ using namespace Unicode; namespace WebCore { -const uint8_t Font::gRoundingHackCharacterTable[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1 /*no-break space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - Font::CodePath Font::s_codePath = Auto; // ============================================================================================ @@ -176,7 +165,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const drawEmphasisMarksForComplexText(context, run, mark, point, from, to); } -float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const +float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { #if ENABLE(SVG_FONTS) if (primaryFont()->isSVGFont()) @@ -194,7 +183,7 @@ float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallb return floatWidthForComplexText(run, fallbackFonts, glyphOverflow); } -float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const +float Font::width(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const { #if !ENABLE(SVG_FONTS) UNUSED_PARAM(extraCharsAvailable); diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h index 258240b..ce03aed 100644 --- a/Source/WebCore/platform/graphics/Font.h +++ b/Source/WebCore/platform/graphics/Font.h @@ -94,9 +94,8 @@ public: void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const; void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const; - int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const { return lroundf(floatWidth(run, fallbackFonts, glyphOverflow)); } - float floatWidth(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const; - float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const; + float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; + float width(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const; int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const; FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const; @@ -129,8 +128,8 @@ public: // Metrics that we query the FontFallbackList for. const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); } - int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); } - float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); } + float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; } + float tabWidth(const SimpleFontData& fontData) const { return 8 * fontData.spaceWidth() + letterSpacing(); } int emphasisMarkAscent(const AtomicString&) const; int emphasisMarkDescent(const AtomicString&) const; int emphasisMarkHeight(const AtomicString&) const; @@ -201,12 +200,6 @@ public: static CodePath codePath(); static CodePath s_codePath; - static const uint8_t gRoundingHackCharacterTable[256]; - static bool isRoundingHackCharacter(UChar32 c) - { - return (((c & ~0xFF) == 0 && gRoundingHackCharacterTable[c])); - } - FontSelector* fontSelector() const; static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; } static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; } diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp index ca82ebd..5b508be 100644 --- a/Source/WebCore/platform/graphics/FontCache.cpp +++ b/Source/WebCore/platform/graphics/FontCache.cpp @@ -261,7 +261,7 @@ typedef HashMap<FontPlatformData, pair<SimpleFontData*, unsigned>, FontDataCache static FontDataCache* gFontDataCache = 0; const int cMaxInactiveFontData = 120; // Pretty Low Threshold -const float cTargetInactiveFontData = 100; +const int cTargetInactiveFontData = 100; static ListHashSet<const SimpleFontData*>* gInactiveFontData = 0; SimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName) diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp index 034ac22..e62df61 100644 --- a/Source/WebCore/platform/graphics/FontFastPath.cpp +++ b/Source/WebCore/platform/graphics/FontFastPath.cpp @@ -297,9 +297,8 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int float afterWidth = it.m_runWidthSoFar; if (run.rtl()) { - float finalRoundingWidth = it.m_finalRoundingWidth; it.advance(run.length()); - initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth; + initialAdvance = it.m_runWidthSoFar - afterWidth; } else initialAdvance = beforeWidth; diff --git a/Source/WebCore/platform/graphics/Gradient.cpp b/Source/WebCore/platform/graphics/Gradient.cpp index 6d0f535..f64fe6b 100644 --- a/Source/WebCore/platform/graphics/Gradient.cpp +++ b/Source/WebCore/platform/graphics/Gradient.cpp @@ -221,7 +221,11 @@ void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra setPlatformGradientSpaceTransform(gradientSpaceTransformation); } +<<<<<<< HEAD #if !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(CAIRO) +======= +#if !USE(SKIA) && !PLATFORM(CAIRO) +>>>>>>> WebKit at r80534 void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&) { } diff --git a/Source/WebCore/platform/graphics/Gradient.h b/Source/WebCore/platform/graphics/Gradient.h index 790e8e1..432262d 100644 --- a/Source/WebCore/platform/graphics/Gradient.h +++ b/Source/WebCore/platform/graphics/Gradient.h @@ -57,11 +57,15 @@ typedef QGradient* PlatformGradient; #elif PLATFORM(CAIRO) typedef struct _cairo_pattern cairo_pattern_t; typedef cairo_pattern_t* PlatformGradient; +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) #include "SkShader.h" typedef class PlatformGradientRec* PlatformGradient; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 class SkShader; typedef class SkShader* PlatformGradient; typedef class SkShader* PlatformPattern; diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp index a0a7ea9..cb991b7 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp @@ -375,7 +375,7 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const } #if !OS(WINCE) || PLATFORM(QT) -void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to) +void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to) { if (paintingDisabled()) return; @@ -384,7 +384,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo } #endif -void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const IntPoint& point, int from, int to) +void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) { if (paintingDisabled()) return; @@ -422,13 +422,13 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F bidiRun = bidiRun->next(); // FIXME: Have Font::drawText return the width of what it drew so that we don't have to re-measure here. if (bidiRun) - currPoint.move(font.floatWidth(subrun), 0.f); + currPoint.move(font.width(subrun), 0); } bidiResolver.deleteRuns(); } -void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const IntPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to) +void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to) { if (paintingDisabled()) return; @@ -550,6 +550,13 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS image->draw(this, styleColorSpace, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op, useLowQualityScale); } +#if !PLATFORM(QT) +void GraphicsContext::clip(const IntRect& rect) +{ + clip(FloatRect(rect)); +} +#endif + void GraphicsContext::addRoundedRectClip(const RoundedIntRect& rect) { if (paintingDisabled()) @@ -649,7 +656,11 @@ CompositeOperator GraphicsContext::compositeOperation() const return m_state.compositeOperator; } +<<<<<<< HEAD #if !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) +======= +#if !USE(SKIA) +>>>>>>> WebKit at r80534 void GraphicsContext::setPlatformFillGradient(Gradient*) { } @@ -667,7 +678,11 @@ void GraphicsContext::setPlatformStrokePattern(Pattern*) } #endif +<<<<<<< HEAD #if !PLATFORM(CG) && !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) +======= +#if !PLATFORM(CG) && !USE(SKIA) +>>>>>>> WebKit at r80534 // Implement this if you want to go ahead and push the drawing mode into your native context // immediately. void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) @@ -675,7 +690,11 @@ void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) } #endif +<<<<<<< HEAD #if !PLATFORM(QT) && !PLATFORM(CAIRO) && !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG) +======= +#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !USE(SKIA) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG) +>>>>>>> WebKit at r80534 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle) { } @@ -687,7 +706,7 @@ void GraphicsContext::setPlatformShouldSmoothFonts(bool) } #endif -#if !PLATFORM(SKIA) +#if !USE(SKIA) void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&) { } diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index 21a9067..f69c340 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -74,6 +74,7 @@ class wxWindowDC; #else typedef wxWindowDC PlatformGraphicsContext; #endif +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) namespace WebCore { @@ -82,6 +83,9 @@ class PlatformGraphicsContext; class SkPaint; struct SkPoint; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 namespace WebCore { class PlatformContextSkia; } @@ -276,6 +280,9 @@ namespace WebCore { // Allow font smoothing (LCD antialiasing). Not part of the graphics state. void setAllowsFontSmoothing(bool); + + void setIsCALayerContext(bool); + bool isCALayerContext() const; #endif #if PLATFORM(ANDROID) @@ -356,6 +363,7 @@ namespace WebCore { void setImageInterpolationQuality(InterpolationQuality); InterpolationQuality imageInterpolationQuality() const; + void clip(const IntRect&); void clip(const FloatRect&); void addRoundedRectClip(const RoundedIntRect&); void addInnerRoundedRectClip(const IntRect&, int thickness); @@ -370,20 +378,20 @@ namespace WebCore { TextDrawingModeFlags textDrawingMode() const; void setTextDrawingMode(TextDrawingModeFlags); - void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1); - void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1); + void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1); + void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1); void drawBidiText(const Font&, const TextRun&, const FloatPoint&); - void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1); + void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1); FloatRect roundToDevicePixels(const FloatRect&); - void drawLineForText(const IntPoint&, int width, bool printing); + void drawLineForText(const FloatPoint&, float width, bool printing); enum TextCheckingLineStyle { TextCheckingSpellingLineStyle, TextCheckingGrammarLineStyle, TextCheckingReplacementLineStyle }; - void drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle); + void drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle); bool paintingDisabled() const; void setPaintingDisabled(bool); @@ -435,6 +443,7 @@ namespace WebCore { void setURLForRect(const KURL&, const IntRect&); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); AffineTransform getCTM() const; #if OS(WINCE) && !PLATFORM(QT) @@ -516,6 +525,10 @@ namespace WebCore { ContextShadow* contextShadow(); #endif +#if PLATFORM(CAIRO) + void pushImageMask(cairo_surface_t*, const FloatRect&); +#endif + #if PLATFORM(GTK) void setGdkExposeEvent(GdkEventExpose*); GdkWindow* gdkWindow() const; diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index d6c1cec..a9db650 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -28,6 +28,7 @@ #include "IntSize.h" #include "GraphicsLayer.h" +#include "GraphicsTypes3D.h" #include "PlatformString.h" #include <wtf/HashMap.h> @@ -42,25 +43,6 @@ #undef VERSION #endif -// GC3D types match the corresponding GL types as defined in OpenGL ES 2.0 -// header file gl2.h from khronos.org. -typedef unsigned int GC3Denum; -typedef unsigned char GC3Dboolean; -typedef unsigned int GC3Dbitfield; -typedef signed char GC3Dbyte; -typedef unsigned char GC3Dubyte; -typedef short GC3Dshort; -typedef unsigned short GC3Dushort; -typedef int GC3Dint; -typedef int GC3Dsizei; -typedef unsigned int GC3Duint; -typedef float GC3Dfloat; -typedef float GC3Dclampf; -typedef signed long int GC3Dintptr; -typedef signed long int GC3Dsizeiptr; - -typedef GC3Duint Platform3DObject; - #if PLATFORM(MAC) #include "ANGLEWebKitBridge.h" #include <OpenGL/OpenGL.h> diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.cpp b/Source/WebCore/platform/graphics/GraphicsLayer.cpp index 84905a9..ca64065 100644 --- a/Source/WebCore/platform/graphics/GraphicsLayer.cpp +++ b/Source/WebCore/platform/graphics/GraphicsLayer.cpp @@ -470,7 +470,7 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe if (m_backgroundColorSet) { writeIndent(ts, indent + 1); - ts << "(backgroundColor " << m_backgroundColor.name() << ")\n"; + ts << "(backgroundColor " << m_backgroundColor.nameForRenderTreeAsText() << ")\n"; } if (!m_transform.isIdentity()) { diff --git a/Source/WebCore/platform/graphics/GraphicsTypes3D.h b/Source/WebCore/platform/graphics/GraphicsTypes3D.h new file mode 100644 index 0000000..ad73336 --- /dev/null +++ b/Source/WebCore/platform/graphics/GraphicsTypes3D.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GraphicsTypes3D_h +#define GraphicsTypes3D_h + +#include <wtf/Forward.h> + +// GC3D types match the corresponding GL types as defined in OpenGL ES 2.0 +// header file gl2.h from khronos.org. +typedef unsigned int GC3Denum; +typedef unsigned char GC3Dboolean; +typedef unsigned int GC3Dbitfield; +typedef signed char GC3Dbyte; +typedef unsigned char GC3Dubyte; +typedef short GC3Dshort; +typedef unsigned short GC3Dushort; +typedef int GC3Dint; +typedef int GC3Dsizei; +typedef unsigned int GC3Duint; +typedef float GC3Dfloat; +typedef float GC3Dclampf; +typedef signed long int GC3Dintptr; +typedef signed long int GC3Dsizeiptr; + +typedef GC3Duint Platform3DObject; + +#endif diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index 984b7d2..f4495ed 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -115,6 +115,11 @@ bool ImageSource::getHotSpot(IntPoint&) const return false; } +size_t ImageSource::bytesDecodedToDetermineProperties() const +{ + return 0; +} + int ImageSource::repetitionCount() { return m_decoder ? m_decoder->repetitionCount() : cAnimationNone; diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h index 70b2cf5..a5c12d6 100644 --- a/Source/WebCore/platform/graphics/ImageSource.h +++ b/Source/WebCore/platform/graphics/ImageSource.h @@ -46,12 +46,16 @@ QT_END_NAMESPACE #elif PLATFORM(CAIRO) struct _cairo_surface; typedef struct _cairo_surface cairo_surface_t; +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) #include "SkString.h" class SkBitmapRef; class PrivateAndroidImageSourceRec; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 namespace WebCore { class NativeImageSkia; } @@ -109,7 +113,7 @@ typedef wxBitmap* NativeImagePtr; #endif #elif PLATFORM(CAIRO) typedef cairo_surface_t* NativeImagePtr; -#elif PLATFORM(SKIA) +#elif USE(SKIA) typedef WebCore::NativeImageSkia* NativeImagePtr; #elif PLATFORM(HAIKU) typedef BBitmap* NativeImagePtr; @@ -188,6 +192,8 @@ public: IntSize frameSizeAtIndex(size_t) const; bool getHotSpot(IntPoint&) const; + size_t bytesDecodedToDetermineProperties() const; + int repetitionCount(); size_t frameCount() const; diff --git a/Source/WebCore/platform/graphics/IntPoint.h b/Source/WebCore/platform/graphics/IntPoint.h index cd5e4d4..d27906b 100644 --- a/Source/WebCore/platform/graphics/IntPoint.h +++ b/Source/WebCore/platform/graphics/IntPoint.h @@ -68,7 +68,7 @@ class wxPoint; typedef struct _point AEEPoint; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkPoint; struct SkIPoint; #endif @@ -153,7 +153,7 @@ public: operator AEEPoint() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) IntPoint(const SkIPoint&); operator SkIPoint() const; operator SkPoint() const; diff --git a/Source/WebCore/platform/graphics/IntRect.h b/Source/WebCore/platform/graphics/IntRect.h index 3a2433d..c413e7a 100644 --- a/Source/WebCore/platform/graphics/IntRect.h +++ b/Source/WebCore/platform/graphics/IntRect.h @@ -64,7 +64,7 @@ typedef struct _Eina_Rectangle Eina_Rectangle; class wxRect; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkRect; struct SkIRect; #endif @@ -186,7 +186,7 @@ public: operator CGRect() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) IntRect(const SkIRect&); operator SkRect() const; operator SkIRect() const; diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp index 8eed0d2..70576a5 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -153,19 +153,27 @@ static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player) struct MediaPlayerFactory { WTF_MAKE_NONCOPYABLE(MediaPlayerFactory); WTF_MAKE_FAST_ALLOCATED; public: - MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs) + MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs, + MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite) : constructor(constructor) , getSupportedTypes(getSupportedTypes) - , supportsTypeAndCodecs(supportsTypeAndCodecs) + , supportsTypeAndCodecs(supportsTypeAndCodecs) + , getSitesInMediaCache(getSitesInMediaCache) + , clearMediaCache(clearMediaCache) + , clearMediaCacheForSite(clearMediaCacheForSite) + { } CreateMediaEnginePlayer constructor; MediaEngineSupportedTypes getSupportedTypes; MediaEngineSupportsType supportsTypeAndCodecs; + MediaEngineGetSitesInMediaCache getSitesInMediaCache; + MediaEngineClearMediaCache clearMediaCache; + MediaEngineClearMediaCacheForSite clearMediaCacheForSite; }; -static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); +static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite); static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current = 0); static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current); @@ -189,12 +197,14 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines() return installedEngines; } -static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType) +static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType, + MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite) { ASSERT(constructor); ASSERT(getSupportedTypes); ASSERT(supportsType); - installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType)); + + installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite)); } static const AtomicString& applicationOctetStream() @@ -281,6 +291,7 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client) , m_volume(1.0f) , m_muted(false) , m_preservesPitch(true) + , m_privateBrowsing(false) #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) , m_playerProxy(0) #endif @@ -354,6 +365,7 @@ void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current) #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) m_private->setMediaPlayerProxy(m_playerProxy); #endif + m_private->setPrivateBrowsingMode(m_privateBrowsing); m_private->setPreload(m_preload); m_private->setPreservesPitch(preservesPitch()); } @@ -698,24 +710,24 @@ double MediaPlayer::maximumDurationToCacheMediaTime() const return m_private->maximumDurationToCacheMediaTime(); } -unsigned long MediaPlayer::decodedFrames() const +unsigned MediaPlayer::decodedFrameCount() const { - return m_private->decodedFrames(); + return m_private->decodedFrameCount(); } -unsigned long MediaPlayer::droppedFrames() const +unsigned MediaPlayer::droppedFrameCount() const { - return m_private->droppedFrames(); + return m_private->droppedFrameCount(); } -unsigned long MediaPlayer::audioBytesDecoded() const +unsigned MediaPlayer::audioDecodedByteCount() const { - return m_private->audioBytesDecoded(); + return m_private->audioDecodedByteCount(); } -unsigned long MediaPlayer::videoBytesDecoded() const +unsigned MediaPlayer::videoDecodedByteCount() const { - return m_private->videoBytesDecoded(); + return m_private->videoDecodedByteCount(); } void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*) @@ -724,6 +736,44 @@ void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*) loadWithNextMediaEngine(m_currentMediaEngine); } +void MediaPlayer::getSitesInMediaCache(Vector<String>& sites) +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (!engines[i]->getSitesInMediaCache) + continue; + Vector<String> engineSites; + engines[i]->getSitesInMediaCache(engineSites); + sites.append(engineSites); + } +} + +void MediaPlayer::clearMediaCache() +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (engines[i]->clearMediaCache) + engines[i]->clearMediaCache(); + } +} + +void MediaPlayer::clearMediaCacheForSite(const String& site) +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (engines[i]->clearMediaCacheForSite) + engines[i]->clearMediaCacheForSite(site); + } +} + +void MediaPlayer::setPrivateBrowsingMode(bool privateBrowsingMode) +{ + m_privateBrowsing = privateBrowsingMode; + m_private->setPrivateBrowsingMode(m_privateBrowsing); +} // Client callbacks. void MediaPlayer::networkStateChanged() diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h index 1112148..f41af01 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.h +++ b/Source/WebCore/platform/graphics/MediaPlayer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -159,11 +159,14 @@ public: } virtual ~MediaPlayer(); - // media engine support + // Media engine support. enum SupportsType { IsNotSupported, IsSupported, MayBeSupported }; static MediaPlayer::SupportsType supportsType(const ContentType&); static void getSupportedTypes(HashSet<String>&); static bool isAvailable(); + static void getSitesInMediaCache(Vector<String>&); + static void clearMediaCache(); + static void clearMediaCacheForSite(const String&); bool supportsFullscreen() const; bool supportsSave() const; @@ -287,10 +290,12 @@ public: double maximumDurationToCacheMediaTime() const; - unsigned long decodedFrames() const; - unsigned long droppedFrames() const; - unsigned long audioBytesDecoded() const; - unsigned long videoBytesDecoded() const; + unsigned decodedFrameCount() const; + unsigned droppedFrameCount() const; + unsigned audioDecodedByteCount() const; + unsigned videoDecodedByteCount() const; + + void setPrivateBrowsingMode(bool); private: MediaPlayer(MediaPlayerClient*); @@ -314,6 +319,7 @@ private: float m_volume; bool m_muted; bool m_preservesPitch; + bool m_privateBrowsing; #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) WebMediaPlayerProxy* m_playerProxy; // not owned or used, passed to m_private #endif @@ -325,8 +331,12 @@ private: typedef MediaPlayerPrivateInterface* (*CreateMediaEnginePlayer)(MediaPlayer*); typedef void (*MediaEngineSupportedTypes)(HashSet<String>& types); typedef MediaPlayer::SupportsType (*MediaEngineSupportsType)(const String& type, const String& codecs); +typedef void (*MediaEngineGetSitesInMediaCache)(Vector<String>&); +typedef void (*MediaEngineClearMediaCache)(); +typedef void (*MediaEngineClearMediaCacheForSite)(const String&); -typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); +typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, + MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite); } diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h index 04b2612..b4490bc 100644 --- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h +++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -136,10 +136,16 @@ public: // it is OK to calculate movie time before refreshing the cached time. virtual double maximumDurationToCacheMediaTime() const { return 0; } - virtual unsigned long decodedFrames() const { return 0; } - virtual unsigned long droppedFrames() const { return 0; } - virtual unsigned long audioBytesDecoded() const { return 0; } - virtual unsigned long videoBytesDecoded() const { return 0; } + virtual unsigned decodedFrameCount() const { return 0; } + virtual unsigned droppedFrameCount() const { return 0; } + virtual unsigned audioDecodedByteCount() const { return 0; } + virtual unsigned videoDecodedByteCount() const { return 0; } + + void getSitesInMediaCache(Vector<String>&) { } + void clearMediaCache() { } + void clearMediaCacheForSite(const String&) { } + + virtual void setPrivateBrowsingMode(bool) { } }; } diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h index 852d88e..31f2cd6 100644 --- a/Source/WebCore/platform/graphics/Path.h +++ b/Source/WebCore/platform/graphics/Path.h @@ -49,7 +49,7 @@ namespace WebCore { class CairoPath; } typedef WebCore::CairoPath PlatformPath; -#elif PLATFORM(SKIA) +#elif USE(SKIA) class SkPath; typedef SkPath PlatformPath; #elif PLATFORM(HAIKU) diff --git a/Source/WebCore/platform/graphics/Pattern.cpp b/Source/WebCore/platform/graphics/Pattern.cpp index 82d0a24..c2c3de0 100644 --- a/Source/WebCore/platform/graphics/Pattern.cpp +++ b/Source/WebCore/platform/graphics/Pattern.cpp @@ -35,7 +35,7 @@ Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY) : m_tileImage(image) , m_repeatX(repeatX) , m_repeatY(repeatY) -#if PLATFORM(SKIA) +#if USE(SKIA) , m_pattern(0) #endif { @@ -53,7 +53,7 @@ void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransf setPlatformPatternSpaceTransform(); } -#if !PLATFORM(SKIA) +#if !USE(SKIA) void Pattern::platformDestroy() { } diff --git a/Source/WebCore/platform/graphics/Pattern.h b/Source/WebCore/platform/graphics/Pattern.h index e215f3d..c88f2fb 100644 --- a/Source/WebCore/platform/graphics/Pattern.h +++ b/Source/WebCore/platform/graphics/Pattern.h @@ -41,7 +41,7 @@ typedef CGPatternRef PlatformPatternPtr; #elif PLATFORM(CAIRO) #include <cairo.h> typedef cairo_pattern_t* PlatformPatternPtr; -#elif PLATFORM(SKIA) +#elif USE(SKIA) class SkShader; typedef SkShader* PlatformPatternPtr; #elif PLATFORM(QT) @@ -79,7 +79,7 @@ public: void platformDestroy(); // Pattern space is an abstract space that maps to the default user space by the transformation 'userSpaceTransformation' -#if PLATFORM(SKIA) +#if USE(SKIA) PlatformPatternPtr platformPattern(const AffineTransform& userSpaceTransformation); #else PlatformPatternPtr createPlatformPattern(const AffineTransform& userSpaceTransformation) const; diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp index f61ecff..0df51a4 100644 --- a/Source/WebCore/platform/graphics/ShadowBlur.cpp +++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp @@ -144,7 +144,6 @@ ShadowBlur::ShadowBlur(float radius, const FloatSize& offset, const Color& color // Instead of integer division, we use 17.15 for fixed-point division. static const int blurSumShift = 15; -static const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride) { @@ -167,6 +166,7 @@ void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, i // However, shadows rendered according to that spec will extend a little further than m_blurRadius, // so we apply a fudge factor to bring the radius down slightly. float stdDev = m_blurRadius / 2; + const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); const float fudgeFactor = 0.88f; diameter = max(2, static_cast<int>(floorf(stdDev * gaussianKernelFactor * fudgeFactor + 0.5f))); } diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp index 2693609..aaab666 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.cpp +++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp @@ -83,6 +83,15 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo float ascent = svgFontFaceElement->ascent() * scale; float descent = svgFontFaceElement->descent() * scale; float lineGap = 0.1f * size; + + SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); + if (!xHeight) { + // Fallback if x_heightAttr is not specified for the font element. + Vector<SVGGlyphIdentifier> letterXGlyphs; + associatedFontElement->getGlyphIdentifiersForString(String("x", 1), letterXGlyphs); + xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale; + } + m_fontMetrics.setUnitsPerEm(unitsPerEm); m_fontMetrics.setAscent(ascent); m_fontMetrics.setDescent(descent); @@ -90,8 +99,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo m_fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap)); m_fontMetrics.setXHeight(xHeight); - SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); - Vector<SVGGlyphIdentifier> spaceGlyphs; associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs); m_spaceWidth = spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale; @@ -108,7 +115,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo m_spaceGlyph = 0; m_zeroWidthSpaceGlyph = 0; determinePitch(); - m_adjustedSpaceWidth = roundf(m_spaceWidth); m_missingGlyphData.fontData = this; m_missingGlyphData.glyph = 0; } @@ -143,7 +149,6 @@ void SimpleFontData::platformGlyphInit() LOG_ERROR("Failed to get glyph page zero."); m_spaceGlyph = 0; m_spaceWidth = 0; - m_adjustedSpaceWidth = 0; determinePitch(); m_zeroWidthSpaceGlyph = 0; m_missingGlyphData.fontData = this; @@ -160,7 +165,6 @@ void SimpleFontData::platformGlyphInit() float width = widthForGlyph(m_spaceGlyph); m_spaceWidth = width; determinePitch(); - m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width); // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE. // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph. diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index 07c2bd1..93d33bb 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -112,7 +112,6 @@ public: float platformWidthForGlyph(Glyph) const; float spaceWidth() const { return m_spaceWidth; } - float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; } #if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX) float syntheticBoldOffset() const { return m_syntheticBoldOffset; } @@ -230,7 +229,6 @@ private: Glyph m_spaceGlyph; float m_spaceWidth; - float m_adjustedSpaceWidth; Glyph m_zeroWidthSpaceGlyph; diff --git a/Source/WebCore/platform/graphics/StringTruncator.cpp b/Source/WebCore/platform/graphics/StringTruncator.cpp index 8468188..fa8f211 100644 --- a/Source/WebCore/platform/graphics/StringTruncator.cpp +++ b/Source/WebCore/platform/graphics/StringTruncator.cpp @@ -92,22 +92,20 @@ static unsigned rightTruncateToBuffer(const String& string, unsigned length, uns return truncatedLength; } -static float stringWidth(const Font& renderer, const UChar* characters, unsigned length, bool disableRoundingHacks) +static float stringWidth(const Font& renderer, const UChar* characters, unsigned length) { TextRun run(characters, length); - if (disableRoundingHacks) - run.disableRoundingHacks(); - return renderer.floatWidth(run); + return renderer.width(run); } -static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer, bool disableRoundingHacks) +static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer) { if (string.isEmpty()) return string; ASSERT(maxWidth >= 0); - float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1, disableRoundingHacks); + float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1); UChar stringBuffer[STRING_BUFFER_SIZE]; unsigned truncatedLength; @@ -123,7 +121,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f truncatedLength = length; } - float width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks); + float width = stringWidth(font, stringBuffer, truncatedLength); if (width <= maxWidth) return string; @@ -159,7 +157,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f truncatedLength = truncateToBuffer(string, length, keepCount, stringBuffer); - width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks); + width = stringWidth(font, stringBuffer, truncatedLength); if (width <= maxWidth) { keepCountForLargestKnownToFit = keepCount; widthForLargestKnownToFit = width; @@ -181,19 +179,19 @@ static String truncateString(const String& string, float maxWidth, const Font& f return String(stringBuffer, truncatedLength); } -String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks) +String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font) { - return truncateString(string, maxWidth, font, centerTruncateToBuffer, disableRoundingHacks); + return truncateString(string, maxWidth, font, centerTruncateToBuffer); } -String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks) +String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font) { - return truncateString(string, maxWidth, font, rightTruncateToBuffer, disableRoundingHacks); + return truncateString(string, maxWidth, font, rightTruncateToBuffer); } -float StringTruncator::width(const String& string, const Font& font, bool disableRoundingHacks) +float StringTruncator::width(const String& string, const Font& font) { - return stringWidth(font, string.characters(), string.length(), disableRoundingHacks); + return stringWidth(font, string.characters(), string.length()); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/StringTruncator.h b/Source/WebCore/platform/graphics/StringTruncator.h index 6791d38..89dc9ef 100644 --- a/Source/WebCore/platform/graphics/StringTruncator.h +++ b/Source/WebCore/platform/graphics/StringTruncator.h @@ -37,9 +37,9 @@ namespace WebCore { class StringTruncator { public: - static String centerTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true); - static String rightTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true); - static float width(const String&, const Font&, bool disableRoundingHacks = true); + static String centerTruncate(const String&, float maxWidth, const Font&); + static String rightTruncate(const String&, float maxWidth, const Font&); + static float width(const String&, const Font&); }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h index ef434bd..4e0980b 100644 --- a/Source/WebCore/platform/graphics/TextRun.h +++ b/Source/WebCore/platform/graphics/TextRun.h @@ -38,8 +38,7 @@ public: ForbidTrailingExpansion }; - TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false, - bool applyRunRounding = true, bool applyWordRounding = true) + TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false) : m_characters(c) , m_len(len) , m_xpos(xpos) @@ -51,8 +50,6 @@ public: , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) - , m_applyRunRounding(applyRunRounding) - , m_applyWordRounding(applyWordRounding) , m_disableSpacing(false) #if ENABLE(SVG_FONTS) , m_referencingRenderObject(0) @@ -61,8 +58,7 @@ public: { } - TextRun(const String& s, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false, - bool applyRunRounding = true, bool applyWordRounding = true) + TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false) : m_characters(s.characters()) , m_len(s.length()) , m_xpos(xpos) @@ -74,8 +70,6 @@ public: , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) - , m_applyRunRounding(applyRunRounding) - , m_applyWordRounding(applyWordRounding) , m_disableSpacing(false) #if ENABLE(SVG_FONTS) , m_referencingRenderObject(0) @@ -98,18 +92,15 @@ public: #endif bool allowTabs() const { return m_allowTabs; } - int xPos() const { return m_xpos; } - int expansion() const { return m_expansion; } + float xPos() const { return m_xpos; } + float expansion() const { return m_expansion; } bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; } bool rtl() const { return m_rtl; } bool ltr() const { return !m_rtl; } bool directionalOverride() const { return m_directionalOverride; } - bool applyRunRounding() const { return m_applyRunRounding; } - bool applyWordRounding() const { return m_applyWordRounding; } bool spacingDisabled() const { return m_disableSpacing; } void disableSpacing() { m_disableSpacing = true; } - void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; } void setRTL(bool b) { m_rtl = b; } void setDirectionalOverride(bool override) { m_directionalOverride = override; } @@ -128,8 +119,8 @@ private: // m_xpos is the x position relative to the left start of the text line, not relative to the left // start of the containing block. In the case of right alignment or center alignment, left start of // the text line is not the same as left start of the containing block. - int m_xpos; - int m_expansion; + float m_xpos; + float m_expansion; TrailingExpansionBehavior m_trailingExpansionBehavior; #if ENABLE(SVG) float m_horizontalGlyphStretch; @@ -137,8 +128,6 @@ private: bool m_allowTabs; bool m_rtl; bool m_directionalOverride; - bool m_applyRunRounding; - bool m_applyWordRounding; bool m_disableSpacing; #if ENABLE(SVG_FONTS) diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp index f6921ef..4d69334 100644 --- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp +++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp @@ -213,15 +213,17 @@ void TiledBackingStore::createTiles() dropOverhangingTiles(); IntRect keepRect = visibleRect; - keepRect.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1.f)); - keepRect.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1.f)); + // Inflates to both sides, so divide inflate delta by 2 + keepRect.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1.f) / 2); + keepRect.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1.f) / 2); keepRect.intersect(contentsRect()); dropTilesOutsideRect(keepRect); IntRect coverRect = visibleRect; - coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1.f)); - coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1.f)); + // Inflates to both sides, so divide inflate delta by 2 + coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1.f) / 2); + coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1.f) / 2); coverRect.intersect(contentsRect()); // Search for the tile position closest to the viewport center that does not yet contain a tile. diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index a1a88da..27b0627 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -48,7 +48,6 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const , m_currentCharacter(0) , m_runWidthSoFar(0) , m_isAfterExpansion(true) - , m_finalRoundingWidth(0) , m_fallbackFonts(fallbackFonts) , m_accountForGlyphBounds(accountForGlyphBounds) , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) @@ -86,11 +85,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) bool rtl = m_run.rtl(); bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled(); - float widthSinceLastRounding = m_runWidthSoFar; - m_runWidthSoFar = floorf(m_runWidthSoFar); - widthSinceLastRounding -= m_runWidthSoFar; - - float lastRoundingWidth = m_finalRoundingWidth; FloatRect bounds; const SimpleFontData* primaryFont = m_font->primaryFont(); @@ -136,7 +130,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) float width; if (c == '\t' && m_run.allowTabs()) { float tabWidth = m_font->tabWidth(*fontData); - width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding, tabWidth); + width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar, tabWidth); } else { width = fontData->widthForGlyph(glyph); @@ -144,13 +138,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text. width *= m_run.horizontalGlyphStretch(); #endif - - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all characters that - // match the width of the space character have the same width as the space character. - if (width == fontData->spaceWidth() && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding()) - width = fontData->adjustedSpaceWidth(); } if (fontData != lastFontData && width) { @@ -179,18 +166,15 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) // Distribute the run's total expansion evenly over all expansion opportunities in the run. if (m_expansion && (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length())) || (m_run.rtl() && currentCharacter))) { - float previousExpansion = m_expansion; if (!treatAsSpace && !m_isAfterExpansion) { // Take the expansion opportunity before this ideograph. m_expansion -= m_expansionPerOpportunity; - int expansion = roundf(previousExpansion) - roundf(m_expansion); - m_runWidthSoFar += expansion; + m_runWidthSoFar += m_expansionPerOpportunity; if (glyphBuffer) - glyphBuffer->expandLastAdvance(expansion); - previousExpansion = m_expansion; + glyphBuffer->expandLastAdvance(m_expansionPerOpportunity); } m_expansion -= m_expansionPerOpportunity; - width += roundf(previousExpansion) - roundf(m_expansion); + width += m_expansionPerOpportunity; m_isAfterExpansion = true; } else m_isAfterExpansion = false; @@ -216,43 +200,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) cp += clusterLength; currentCharacter += clusterLength; - // Account for float/integer impedance mismatch between CG and KHTML. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // If we move KHTML to floats we can remove this (and related) hacks. - - float oldWidth = width; - - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so following words will start on an integer boundary. - if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) { - width = ceilf(width); - - // Since widthSinceLastRounding can lose precision if we include measurements for - // preceding whitespace, we bypass it here. - m_runWidthSoFar += width; - - // Since this is a rounding hack character, we should have reset this sum on the previous - // iteration. - ASSERT(!widthSinceLastRounding); - } else { - // Check to see if the next character is a "rounding hack character", if so, adjust - // width so that the total run width will be on an integer boundary. - if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp)) - || (m_run.applyRunRounding() && currentCharacter >= m_end)) { - float totalWidth = widthSinceLastRounding + width; - widthSinceLastRounding = ceilf(totalWidth); - width += widthSinceLastRounding - totalWidth; - m_runWidthSoFar += widthSinceLastRounding; - widthSinceLastRounding = 0; - } else - widthSinceLastRounding += width; - } + m_runWidthSoFar += width; if (glyphBuffer) - glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); - - lastRoundingWidth = width - oldWidth; + glyphBuffer->add(glyph, fontData, width); if (m_accountForGlyphBounds) { m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.maxY()); @@ -262,8 +213,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) } m_currentCharacter = currentCharacter; - m_runWidthSoFar += widthSinceLastRounding; - m_finalRoundingWidth = lastRoundingWidth; } bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer) diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h index 2b4f051..8cb89cf 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.h +++ b/Source/WebCore/platform/graphics/WidthIterator.h @@ -53,7 +53,6 @@ struct WidthIterator { float m_expansion; float m_expansionPerOpportunity; bool m_isAfterExpansion; - float m_finalRoundingWidth; private: UChar32 normalizeVoicingMarks(int currentCharacter); diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index 2b4a39e..e9663a6 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -38,6 +38,7 @@ #include "ScaleTransformOperation.h" #include "SystemTime.h" #include "TranslateTransformOperation.h" +#include <QuartzCore/CATransform3D.h> #include <limits.h> #include <wtf/CurrentTime.h> #include <wtf/text/StringConcatenate.h> @@ -1680,8 +1681,8 @@ const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const Ani return animValue->timingFunction(); if (anim->isTimingFunctionSet()) return anim->timingFunction().get(); - - return 0; + + return CubicBezierTimingFunction::defaultTimingFunction(); } bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim) @@ -1759,23 +1760,29 @@ bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& va basicAnim->setToValue(toTransform); } else { if (isTransformTypeNumber(transformOpType)) { - float value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + float fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + float toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } else if (isTransformTypeFloatPoint3D(transformOpType)) { - FloatPoint3D value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + FloatPoint3D fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + FloatPoint3D toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } else { - TransformationMatrix value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + TransformationMatrix fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + TransformationMatrix toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } } diff --git a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp index 27805e6..0ef5fd0 100644 --- a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp +++ b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp @@ -24,12 +24,12 @@ */ #include "config.h" +#include "TransformationMatrix.h" #if PLATFORM(CA) -#include "TransformationMatrix.h" - #include "FloatConversion.h" +#include <QuartzCore/CATransform3D.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm index 506bd40..c8ed948 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm @@ -135,9 +135,7 @@ static PlatformCAAnimation::ValueFunctionType fromCAValueFunctionType(NSString* static CAMediaTimingFunction* toCAMediaTimingFunction(const TimingFunction* timingFunction) { - if (!timingFunction) - return [CAMediaTimingFunction functionWithControlPoints:0.25f :0.1f :0.25f :0.1f]; - + ASSERT(timingFunction); if (timingFunction->isCubicBezierTimingFunction()) { const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction); return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(ctf->x1()) :static_cast<float>(ctf->y1()) @@ -145,8 +143,6 @@ static CAMediaTimingFunction* toCAMediaTimingFunction(const TimingFunction* timi } return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - - return 0; } PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(AnimationType type, const String& keyPath) diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp index 9dc30ea..f2e1950 100644 --- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp @@ -35,6 +35,7 @@ #include "WKCACFViewLayerTreeHost.h" #include "WebCoreInstanceHandle.h" #include <limits.h> +#include <QuartzCore/CABase.h> #include <wtf/CurrentTime.h> #include <wtf/OwnArrayPtr.h> diff --git a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp index 772244b..228e16e 100644 --- a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp @@ -29,6 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "PlatformCALayer.h" +#include <QuartzCore/CABase.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #ifndef NDEBUG diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp index 6e3011b..549f2f8 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp @@ -124,9 +124,7 @@ static PlatformCAAnimation::ValueFunctionType fromCACFValueFunctionType(CFString static RetainPtr<CACFTimingFunctionRef> toCACFTimingFunction(const TimingFunction* timingFunction) { - if (!timingFunction) - return RetainPtr<CACFTimingFunctionRef>(AdoptCF, CACFTimingFunctionCreate(0.25f, 0.1f, 0.25f, 0.1f)); - + ASSERT(timingFunction); if (timingFunction->isCubicBezierTimingFunction()) { const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction); return RetainPtr<CACFTimingFunctionRef>(AdoptCF, CACFTimingFunctionCreate(static_cast<float>(ctf->x1()), static_cast<float>(ctf->y1()), static_cast<float>(ctf->x2()), static_cast<float>(ctf->y2()))); diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index cdbfc57..e69a7a5 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> - * Copyright (C) 2010 Igalia S.L. + * Copyright (C) 2010, 2011 Igalia S.L. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ #include "CairoPath.h" #include "CairoUtilities.h" #include "ContextShadow.h" +#include "FloatConversion.h" #include "FloatRect.h" #include "Font.h" #include "GraphicsContextPlatformPrivateCairo.h" @@ -229,12 +230,19 @@ void GraphicsContext::savePlatformState() cairo_save(m_data->cr); m_data->save(); m_data->shadowStack.append(m_data->shadow); + m_data->maskImageStack.append(ImageMaskInformation()); } void GraphicsContext::restorePlatformState() { - cairo_restore(m_data->cr); - m_data->restore(); + cairo_t* cr = m_data->cr; + const ImageMaskInformation& maskInformation = m_data->maskImageStack.last(); + if (maskInformation.isValid()) { + const FloatRect& maskRect = maskInformation.maskRect(); + cairo_pop_group_to_source(cr); + cairo_mask_surface(cr, maskInformation.maskSurface(), maskRect.x(), maskRect.y()); + } + m_data->maskImageStack.removeLast(); if (m_data->shadowStack.isEmpty()) m_data->shadow = ContextShadow(); @@ -242,6 +250,9 @@ void GraphicsContext::restorePlatformState() m_data->shadow = m_data->shadowStack.last(); m_data->shadowStack.removeLast(); } + + cairo_restore(m_data->cr); + m_data->restore(); } // Draws a filled rectangle with a stroked border. @@ -701,20 +712,22 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int cairo_restore(cr); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; - IntPoint endPoint = origin + IntSize(width, 0); - drawLine(origin, endPoint); + FloatPoint endPoint = origin + FloatSize(width, 0); + + // FIXME: Loss of precision here. Might consider rounding. + drawLine(IntPoint(origin.x(), origin.y()), IntPoint(endPoint.x(), endPoint.y())); } #if !PLATFORM(GTK) #include "DrawErrorUnderline.h" #endif -void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -754,16 +767,30 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) x = round(x); y = round(y); cairo_device_to_user(cr, &x, &y); - result.setX(static_cast<float>(x)); - result.setY(static_cast<float>(y)); - x = frect.width(); - y = frect.height(); - cairo_user_to_device_distance(cr, &x, &y); - x = round(x); - y = round(y); - cairo_device_to_user_distance(cr, &x, &y); - result.setWidth(static_cast<float>(x)); - result.setHeight(static_cast<float>(y)); + result.setX(narrowPrecisionToFloat(x)); + result.setY(narrowPrecisionToFloat(y)); + + // We must ensure width and height are at least 1 (or -1) when + // we're given float values in the range between 0 and 1 (or -1 and 0). + double width = frect.width(); + double height = frect.height(); + cairo_user_to_device_distance(cr, &width, &height); + if (width > -1 && width < 0) + width = -1; + else if (width > 0 && width < 1) + width = 1; + else + width = round(width); + if (height > -1 && width < 0) + height = -1; + else if (height > 0 && height < 1) + height = 1; + else + height = round(height); + cairo_device_to_user_distance(cr, &width, &height); + result.setWidth(narrowPrecisionToFloat(width)); + result.setHeight(narrowPrecisionToFloat(height)); + return result; } @@ -838,6 +865,17 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->concatCTM(transform); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + cairo_t* cr = m_data->cr; + const cairo_matrix_t matrix = cairo_matrix_t(transform); + cairo_set_matrix(cr, &matrix); + m_data->setCTM(transform); +} + void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { if (paintingDisabled()) @@ -1144,6 +1182,33 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const return InterpolationDefault; } +void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& rect) +{ + // We must call savePlatformState at least once before we can use image masking, + // since we actually apply the mask in restorePlatformState. + ASSERT(!m_data->maskImageStack.isEmpty()); + m_data->maskImageStack.last().update(surface, rect); + + // Cairo doesn't support the notion of an image clip, so we push a group here + // and then paint it to the surface with an image mask (which is an immediate + // operation) during restorePlatformState. + + // We want to allow the clipped elements to composite with the surface as it + // is now, but they are isolated in another group. To make this work, we're + // going to blit the current surface contents onto the new group once we push it. + cairo_t* cr = m_data->cr; + cairo_surface_t* currentTarget = cairo_get_target(cr); + cairo_surface_flush(currentTarget); + + // Pushing a new group ensures that only things painted after this point are clipped. + cairo_push_group(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + + cairo_set_source_surface(cr, currentTarget, 0, 0); + cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); + cairo_fill(cr); +} + } // namespace WebCore #endif // PLATFORM(CAIRO) diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h index a0dfc8c..924f69a 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h @@ -31,6 +31,7 @@ #include "GraphicsContext.h" #include "ContextShadow.h" +#include "RefPtrCairo.h" #include <cairo.h> #include <math.h> #include <stdio.h> @@ -45,6 +46,25 @@ typedef struct _GdkExposeEvent GdkExposeEvent; namespace WebCore { +// In Cairo image masking is immediate, so to emulate image clipping we must save masking +// details as part of the context state and apply it during platform restore. +class ImageMaskInformation { +public: + void update(cairo_surface_t* maskSurface, const FloatRect& maskRect) + { + m_maskSurface = maskSurface; + m_maskRect = maskRect; + } + + bool isValid() const { return m_maskSurface; } + cairo_surface_t* maskSurface() const { return m_maskSurface.get(); } + const FloatRect& maskRect() const { return m_maskRect; } + +private: + RefPtr<cairo_surface_t> m_maskSurface; + FloatRect m_maskRect; +}; + class GraphicsContextPlatformPrivate { public: GraphicsContextPlatformPrivate() @@ -76,7 +96,7 @@ public: void rotate(float); void translate(float, float); void concatCTM(const AffineTransform&); - void concatCTM(const TransformationMatrix&); + void setCTM(const AffineTransform&); void beginTransparencyLayer() { m_transparencyCount++; } void endTransparencyLayer() { m_transparencyCount--; } void syncContext(PlatformGraphicsContext* cr); @@ -91,7 +111,7 @@ public: void rotate(float) {} void translate(float, float) {} void concatCTM(const AffineTransform&) {} - void concatCTM(const TransformationMatrix&) {} + void setCTM(const AffineTransform&) {} void beginTransparencyLayer() {} void endTransparencyLayer() {} void syncContext(PlatformGraphicsContext* cr) {} @@ -102,6 +122,7 @@ public: ContextShadow shadow; Vector<ContextShadow> shadowStack; + Vector<ImageMaskInformation> maskImageStack; #if PLATFORM(GTK) GdkEventExpose* expose; diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp index f7d6040..9ee8a94 100644 --- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp @@ -112,10 +112,9 @@ PassRefPtr<Image> ImageBuffer::copyImage() const return BitmapImage::create(copySurface(m_data.m_surface)); } -void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& maskRect) const { - notImplemented(); - // See https://bugs.webkit.org/show_bug.cgi?id=23526 for why this is unimplemented. + context->pushImageMask(m_data.m_surface, maskRect); } void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp index 0113427..7a09a52 100644 --- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -170,6 +170,11 @@ void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle } } +static inline float areaOfTriangleFormedByPoints(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3) +{ + return p1.x() * (p2.y() - p3.y()) + p2.x() * (p3.y() - p1.y()) + p3.x() * (p1.y() - p2.y()); +} + void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { if (isEmpty()) @@ -180,7 +185,11 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) double x0, y0; cairo_get_current_point(cr, &x0, &y0); FloatPoint p0(x0, y0); - if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || radius == 0.f) { + + // Draw only a straight line to p1 if any of the points are equal or the radius is zero + // or the points are collinear (triangle that the points form has area of zero value). + if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || !radius + || !areaOfTriangleFormedByPoints(p0, p1, p2)) { cairo_line_to(cr, p1.x(), p1.y()); return; } diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 3591479..dbcab45 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -65,6 +65,11 @@ #endif +// Undocumented CGContextSetCTM function, available at least since 10.4. +extern "C" { + CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform); +}; + using namespace std; namespace WebCore { @@ -603,12 +608,42 @@ void GraphicsContext::strokePath(const Path& path) CGContextAddPath(context, path.platformPath()); if (m_state.strokeGradient) { - CGContextSaveGState(context); - CGContextReplacePathWithStrokedPath(context); - CGContextClip(context); - CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); - m_state.strokeGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + FloatRect rect = path.boundingRect(); + float lineWidth = strokeThickness(); + float doubleLineWidth = lineWidth * 2; + float layerWidth = ceilf(rect.width() + doubleLineWidth); + float layerHeight = ceilf(rect.height() + doubleLineWidth); + + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(layerWidth, layerHeight), 0); + CGContextRef layerContext = CGLayerGetContext(layer); + CGContextSetLineWidth(layerContext, lineWidth); + + // Compensate for the line width, otherwise the layer's top-left corner would be + // aligned with the rect's top-left corner. This would result in leaving pixels out of + // the layer on the left and top sides. + float translationX = lineWidth - rect.x(); + float translationY = lineWidth - rect.y(); + CGContextTranslateCTM(layerContext, translationX, translationY); + + CGContextAddPath(layerContext, path.platformPath()); + CGContextReplacePathWithStrokedPath(layerContext); + CGContextClip(layerContext); + CGContextConcatCTM(layerContext, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(layerContext); + + float destinationX = roundf(rect.x() - lineWidth); + float destinationY = roundf(rect.y() - lineWidth); + CGContextDrawLayerAtPoint(context, CGPointMake(destinationX, destinationY), layer); + CGLayerRelease(layer); + } else { + CGContextSaveGState(context); + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(this); + CGContextRestoreGState(context); + } return; } @@ -952,7 +987,7 @@ void GraphicsContext::clearRect(const FloatRect& r) CGContextClearRect(platformContext(), r); } -void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) +void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) { if (paintingDisabled()) return; @@ -960,19 +995,49 @@ void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) CGContextRef context = platformContext(); if (m_state.strokeGradient) { - CGContextSaveGState(context); - setStrokeThickness(lineWidth); - CGContextAddRect(context, r); - CGContextReplacePathWithStrokedPath(context); - CGContextClip(context); - m_state.strokeGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + const float doubleLineWidth = lineWidth * 2; + const float layerWidth = ceilf(rect.width() + doubleLineWidth); + const float layerHeight = ceilf(rect.height() + doubleLineWidth); + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(layerWidth, layerHeight), 0); + + CGContextRef layerContext = CGLayerGetContext(layer); + m_state.strokeThickness = lineWidth; + CGContextSetLineWidth(layerContext, lineWidth); + + // Compensate for the line width, otherwise the layer's top-left corner would be + // aligned with the rect's top-left corner. This would result in leaving pixels out of + // the layer on the left and top sides. + const float translationX = lineWidth - rect.x(); + const float translationY = lineWidth - rect.y(); + CGContextTranslateCTM(layerContext, translationX, translationY); + + CGContextAddRect(layerContext, rect); + CGContextReplacePathWithStrokedPath(layerContext); + CGContextClip(layerContext); + CGContextConcatCTM(layerContext, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(layerContext); + + const float destinationX = roundf(rect.x() - lineWidth); + const float destinationY = roundf(rect.y() - lineWidth); + CGContextDrawLayerAtPoint(context, CGPointMake(destinationX, destinationY), layer); + CGLayerRelease(layer); + } else { + CGContextSaveGState(context); + setStrokeThickness(lineWidth); + CGContextAddRect(context, rect); + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(this); + CGContextRestoreGState(context); + } return; } if (m_state.strokePattern) applyStrokePattern(); - CGContextStrokeRectWithWidth(context, r, lineWidth); + CGContextStrokeRectWithWidth(context, rect, lineWidth); } void GraphicsContext::setLineCap(LineCap cap) @@ -1085,6 +1150,15 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->m_userToDeviceTransformKnownToBeIdentity = false; } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + CGContextSetCTM(platformContext(), transform); + m_data->setCTM(transform); + m_data->m_userToDeviceTransformKnownToBeIdentity = false; +} + AffineTransform GraphicsContext::getCTM() const { CGAffineTransform t = CGContextGetCTM(platformContext()); @@ -1130,7 +1204,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); } -void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing) { if (paintingDisabled()) return; @@ -1269,6 +1343,16 @@ void GraphicsContext::setAllowsFontSmoothing(bool allowsFontSmoothing) #endif } +void GraphicsContext::setIsCALayerContext(bool) +{ + m_data->m_isCALayerContext = true; +} + +bool GraphicsContext::isCALayerContext() const +{ + return m_data->m_isCALayerContext; +} + void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) { if (paintingDisabled()) diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h index d4fa32e..f9255df 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h @@ -33,7 +33,7 @@ namespace WebCore { class GraphicsContextPlatformPrivate { public: - GraphicsContextPlatformPrivate(CGContextRef cgContext) + GraphicsContextPlatformPrivate(CGContextRef cgContext, bool isLayerContext = false) : m_cgContext(cgContext) #if PLATFORM(WIN) , m_hdc(0) @@ -41,6 +41,7 @@ public: , m_shouldIncludeChildWindows(false) #endif , m_userToDeviceTransformKnownToBeIdentity(false) + , m_isCALayerContext(isLayerContext) { } @@ -59,6 +60,7 @@ public: void rotate(float) {} void translate(float, float) {} void concatCTM(const AffineTransform&) {} + void setCTM(const AffineTransform&) {} void beginTransparencyLayer() {} void endTransparencyLayer() {} #endif @@ -74,6 +76,7 @@ public: void rotate(float); void translate(float, float); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); void beginTransparencyLayer() { m_transparencyCount++; } void endTransparencyLayer() { m_transparencyCount--; } @@ -84,6 +87,7 @@ public: RetainPtr<CGContextRef> m_cgContext; bool m_userToDeviceTransformKnownToBeIdentity; + bool m_isCALayerContext; }; } diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp index ab5907e..7c8e313 100644 --- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -244,21 +244,21 @@ void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& src } } -void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const +void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) const { - CGContextRef platformContext = context->platformContext(); + CGContextRef platformContextToClip = contextToClip->platformContext(); RetainPtr<CGImageRef> image; if (!m_accelerateRendering) image.adoptCF(cgImage(m_size, m_data)); #if USE(IOSURFACE_CANVAS_BACKING_STORE) else - image.adoptCF(wkIOSurfaceContextCreateImage(platformContext)); + image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext())); #endif - CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height()); - CGContextScaleCTM(platformContext, 1, -1); - CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get()); - CGContextScaleCTM(platformContext, 1, -1); - CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height()); + CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + rect.height()); + CGContextScaleCTM(platformContextToClip, 1, -1); + CGContextClipToMask(platformContextToClip, FloatRect(FloatPoint(), rect.size()), image.get()); + CGContextScaleCTM(platformContextToClip, 1, -1); + CGContextTranslateCTM(platformContextToClip, -rect.x(), -rect.y() - rect.height()); } template <Multiply multiplied> diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp index 4ed8684..068ea5b 100644 --- a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp @@ -40,7 +40,12 @@ using namespace std; namespace WebCore { -static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); +const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); + +// kCGImagePropertyGIFUnclampedDelayTime is available in the ImageIO framework headers on some versions +// of SnowLeopard. It's not possible to detect whether the constant is available so we define our own here +// that won't conflict with ImageIO's version when it is available. +const CFStringRef WebCoreCGImagePropertyGIFUnclampedDelayTime = CFSTR("UnclampedDelayTime"); #if !PLATFORM(MAC) size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count) @@ -222,6 +227,17 @@ bool ImageSource::getHotSpot(IntPoint& hotSpot) const return true; } +size_t ImageSource::bytesDecodedToDetermineProperties() const +{ + // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64. + // A non-zero value ensures cached images with no decoded frames still enter + // the live decoded resources list when the CGImageSource decodes image + // properties, allowing the cache to prune the partially decoded image. + // This value is likely to be inaccurate on other platforms, but the overall + // behavior is unchanged. + return 13088; +} + int ImageSource::repetitionCount() { int result = cAnimationLoopOnce; // No property means loop once. @@ -301,9 +317,13 @@ float ImageSource::frameDurationAtIndex(size_t index) if (properties) { CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); if (typeProperties) { - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime); - if (num) + if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, WebCoreCGImagePropertyGIFUnclampedDelayTime)) { + // Use the unclamped frame delay if it exists. + CFNumberGetValue(num, kCFNumberFloatType, &duration); + } else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime)) { + // Fall back to the clamped frame delay if the unclamped frame delay does not exist. CFNumberGetValue(num, kCFNumberFloatType, &duration); + } } } diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h index 44ef050..a14cb98 100644 --- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h @@ -45,7 +45,7 @@ class Canvas2DLayerChromium : public CanvasLayerChromium { public: static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner); virtual ~Canvas2DLayerChromium(); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void updateContentsIfDirty(); void setTextureChanged(); diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp index 4aef25b..0264868 100644 --- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp @@ -34,6 +34,7 @@ #include "CanvasLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" @@ -41,64 +42,11 @@ namespace WebCore { unsigned CanvasLayerChromium::m_shaderProgramId = 0; -CanvasLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_canvasShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - - // Canvas layers need to be flipped vertically and their colors shouldn't be - // swizzled. - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_canvasShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_canvasShaderProgram) { - LOG_ERROR("CanvasLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_canvasShaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_canvasShaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_canvasShaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -CanvasLayerChromium::SharedValues::~SharedValues() -{ - if (m_canvasShaderProgram) - GLC(m_context, m_context->deleteProgram(m_canvasShaderProgram)); -} - CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner) : LayerChromium(owner) , m_textureChanged(true) , m_textureId(0) + , m_premultipliedAlpha(true) { } @@ -109,17 +57,19 @@ CanvasLayerChromium::~CanvasLayerChromium() void CanvasLayerChromium::draw() { ASSERT(layerRenderer()); - const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const CanvasLayerChromium::Program* program = layerRenderer()->canvasLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId)); - layerRenderer()->useShader(sv->canvasShaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); - + GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA; + GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } } diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h index 6520b55..ed3a06f 100644 --- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h @@ -45,30 +45,16 @@ public: virtual void draw(); - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned canvasShaderProgram() const { return m_canvasShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_canvasShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program; protected: explicit CanvasLayerChromium(GraphicsLayerChromium* owner); + + virtual const char* layerTypeAsString() const { return "CanvasLayer"; } + bool m_textureChanged; unsigned m_textureId; + bool m_premultipliedAlpha; private: static unsigned m_shaderProgramId; diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp index a38f6bd..78f93d5 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp @@ -34,97 +34,15 @@ #include "ContentLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "LayerTexture.h" #include "RenderLayerBacking.h" - -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#include "SkColorPriv.h" -#include "skia/ext/platform_canvas.h" -#elif PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#endif +#include "TextStream.h" namespace WebCore { -ContentLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_contentShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - // Shaders for drawing the layer contents. - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - -#if PLATFORM(SKIA) - // Color is in RGBA order. - char rgbaFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = texColor * alpha; \n" - "} \n"; -#endif - - // Color is in BGRA order. - char bgraFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n" - "} \n"; - -#if PLATFORM(SKIA) - // Assuming the packing is either Skia default RGBA or Chromium default BGRA. - char* fragmentShaderString = SK_B32_SHIFT ? rgbaFragmentShaderString : bgraFragmentShaderString; -#else - char* fragmentShaderString = bgraFragmentShaderString; -#endif - m_contentShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_contentShaderProgram) { - LOG_ERROR("ContentLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_contentShaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_contentShaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_contentShaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -ContentLayerChromium::SharedValues::~SharedValues() -{ - if (m_contentShaderProgram) - GLC(m_context, m_context->deleteProgram(m_contentShaderProgram)); -} - - PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner) { return adoptRef(new ContentLayerChromium(owner)); @@ -154,9 +72,9 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const // one of the layer's dimensions is larger than 2000 pixels or the size of // surface it's rendering into. This is a temporary measure until layer tiling is implemented. static const int maxLayerSize = 2000; - return (m_bounds.width() > max(maxLayerSize, m_targetRenderSurface->contentRect().width()) - || m_bounds.height() > max(maxLayerSize, m_targetRenderSurface->contentRect().height()) - || !layerRenderer()->checkTextureSize(m_bounds)); + return (bounds().width() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().width()) + || bounds().height() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().height()) + || !layerRenderer()->checkTextureSize(bounds())); } void ContentLayerChromium::updateContentsIfDirty() @@ -169,28 +87,25 @@ void ContentLayerChromium::updateContentsIfDirty() ASSERT(layerRenderer()); - void* pixels = 0; IntRect dirtyRect; - IntRect updateRect; - IntSize requiredTextureSize; - IntSize bitmapSize; - IntRect boundsRect(IntPoint(0, 0), m_bounds); + IntRect boundsRect(IntPoint(0, 0), bounds()); + IntPoint paintingOffset; // FIXME: Remove this test when tiled layers are implemented. if (requiresClippedUpdateRect()) { // A layer with 3D transforms could require an arbitrarily large number // of texels to be repainted, so ignore these layers until tiling is // implemented. - if (!drawTransform().isIdentityOrTranslation()) { + if (!ccLayerImpl()->drawTransform().isIdentityOrTranslation()) { m_skipsDraw = true; return; } // Calculate the region of this layer that is currently visible. - const IntRect clipRect = m_targetRenderSurface->contentRect(); + const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect(); - TransformationMatrix layerOriginTransform = drawTransform(); - layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0); + TransformationMatrix layerOriginTransform = ccLayerImpl()->drawTransform(); + layerOriginTransform.translate3d(-0.5 * bounds().width(), -0.5 * bounds().height(), 0); // For now we apply the large layer treatment only for layers that are either untransformed // or are purely translated. Their matrix is expected to be invertible. @@ -198,7 +113,7 @@ void ContentLayerChromium::updateContentsIfDirty() TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse(); IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect); - visibleRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height())); + visibleRectInLayerCoords.intersect(IntRect(0, 0, bounds().width(), bounds().height())); // For normal layers, the center of the texture corresponds with the center of the layer. // In large layers the center of the texture is the center of the visible region so we have @@ -212,9 +127,13 @@ void ContentLayerChromium::updateContentsIfDirty() return; } - // If the visible portion of the layer is different from the last upload, or if our backing - // texture has been evicted, then the whole layer is considered dirty. - if (visibleRectInLayerCoords != m_visibleRectInLayerCoords || !m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA)) + // If we need to resize the upload buffer we have to repaint everything. + if (m_canvas.size() != visibleRectInLayerCoords.size()) { + resizeUploadBuffer(visibleRectInLayerCoords.size()); + m_dirtyRect = boundsRect; + } + // If the visible portion of the layer is different from the last upload. + if (visibleRectInLayerCoords != m_visibleRectInLayerCoords) m_dirtyRect = boundsRect; m_visibleRectInLayerCoords = visibleRectInLayerCoords; @@ -224,92 +143,52 @@ void ContentLayerChromium::updateContentsIfDirty() // What the rectangles mean: // dirtyRect: The region of this layer that will be updated. - // updateRect: The region of the layer's texture that will be uploaded into. - // requiredTextureSize: is the required size of this layer's texture. + // m_uploadUpdateRect: The region of the layer's texture that will be uploaded into. dirtyRect = visibleDirtyRectInLayerSpace; - updateRect = dirtyRect; + m_uploadUpdateRect = dirtyRect; IntSize visibleRectOffsetInLayerCoords(visibleRectInLayerCoords.x(), visibleRectInLayerCoords.y()); - updateRect.move(-visibleRectOffsetInLayerCoords); - requiredTextureSize = visibleRectInLayerCoords.size(); + paintingOffset = IntPoint(visibleRectOffsetInLayerCoords); + m_uploadUpdateRect.move(-visibleRectOffsetInLayerCoords); } else { dirtyRect = IntRect(m_dirtyRect); - requiredTextureSize = m_bounds; // If the texture needs to be reallocated then we must redraw the entire // contents of the layer. - if (!m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA)) + if (m_canvas.size() != bounds()) { + resizeUploadBuffer(bounds()); dirtyRect = boundsRect; - else { + } else { // Clip the dirtyRect to the size of the layer to avoid drawing // outside the bounds of the backing texture. dirtyRect.intersect(boundsRect); } - updateRect = dirtyRect; + m_uploadUpdateRect = dirtyRect; } if (dirtyRect.isEmpty()) return; -#if PLATFORM(SKIA) - const SkBitmap* skiaBitmap = 0; - OwnPtr<skia::PlatformCanvas> canvas; - OwnPtr<PlatformContextSkia> skiaContext; - OwnPtr<GraphicsContext> graphicsContext; - - canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false)); - skiaContext.set(new PlatformContextSkia(canvas.get())); - - // This is needed to get text to show up correctly. - // FIXME: Does this take us down a very slow text rendering path? - skiaContext->setDrawingToImageBuffer(true); - - graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get()))); + PlatformCanvas::Painter painter(&m_canvas); + painter.context()->save(); + painter.context()->translate(-paintingOffset.x(), -paintingOffset.y()); + painter.context()->clearRect(dirtyRect); + painter.context()->clip(dirtyRect); - // Bring the canvas into the coordinate system of the paint rect. - canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y())); + m_owner->paintGraphicsLayerContents(*painter.context(), dirtyRect); + painter.context()->restore(); +} - m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect); - const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); - skiaBitmap = &bitmap; - ASSERT(skiaBitmap); +void ContentLayerChromium::resizeUploadBuffer(const IntSize& size) +{ + m_canvas.resize(size); +} - SkAutoLockPixels lock(*skiaBitmap); - SkBitmap::Config skiaConfig = skiaBitmap->config(); - // FIXME: do we need to support more image configurations? - if (skiaConfig == SkBitmap::kARGB_8888_Config) { - pixels = skiaBitmap->getPixels(); - bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height()); - } -#elif PLATFORM(CG) - Vector<uint8_t> tempVector; - int rowBytes = 4 * dirtyRect.width(); - tempVector.resize(rowBytes * dirtyRect.height()); - memset(tempVector.data(), 0, tempVector.size()); - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); - RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(), - dirtyRect.width(), dirtyRect.height(), 8, rowBytes, - colorSpace.get(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height()); - CGContextScaleCTM(contextCG.get(), 1, -1); - - GraphicsContext graphicsContext(contextCG.get()); - - // Translate the graphics context into the coordinate system of the dirty rect. - graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y()); - - m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect); - - pixels = tempVector.data(); - bitmapSize = dirtyRect.size(); -#else -#error "Need to implement for your platform." -#endif - - if (pixels) - updateTextureRect(pixels, requiredTextureSize, updateRect); +void ContentLayerChromium::updateTextureIfNeeded() +{ + PlatformCanvas::AutoLocker locker(&m_canvas); + updateTexture(locker.pixels(), m_canvas.size()); } -void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect) +void ContentLayerChromium::updateTexture(const uint8_t* pixels, const IntSize& size) { if (!pixels) return; @@ -318,15 +197,43 @@ void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requir if (!m_contentsTexture) m_contentsTexture = LayerTexture::create(context, layerRenderer()->textureManager()); - if (!m_contentsTexture->reserve(requiredTextureSize, GraphicsContext3D::RGBA)) { + // If we have to allocate a new texture we have to upload the full contents. + if (!m_contentsTexture->isValid(size, GraphicsContext3D::RGBA)) + m_uploadUpdateRect = IntRect(IntPoint(0, 0), size); + + if (!m_contentsTexture->reserve(size, GraphicsContext3D::RGBA)) { m_skipsDraw = true; return; } - m_contentsTexture->bindTexture(); + IntRect srcRect = IntRect(IntPoint(0, 0), size); + if (requiresClippedUpdateRect()) + srcRect = m_visibleRectInLayerCoords; + + const size_t destStride = m_uploadUpdateRect.width() * 4; + const size_t srcStride = srcRect.width() * 4; + + const uint8_t* uploadPixels = pixels + srcStride * m_uploadUpdateRect.y(); + Vector<uint8_t> uploadBuffer; + if (srcStride != destStride || m_uploadUpdateRect.x()) { + uploadBuffer.resize(m_uploadUpdateRect.height() * destStride); + for (int row = 0; row < m_uploadUpdateRect.height(); ++row) { + size_t srcOffset = (m_uploadUpdateRect.y() + row) * srcStride + m_uploadUpdateRect.x() * 4; + ASSERT(srcOffset + destStride <= static_cast<size_t>(size.width() * size.height() * 4)); + size_t destOffset = row * destStride; + ASSERT(destOffset + destStride <= uploadBuffer.size()); + memcpy(uploadBuffer.data() + destOffset, pixels + srcOffset, destStride); + } + uploadPixels = uploadBuffer.data(); + } - GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); + m_contentsTexture->bindTexture(); + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, + m_uploadUpdateRect.x(), m_uploadUpdateRect.y(), m_uploadUpdateRect.width(), m_uploadUpdateRect.height(), + GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, + uploadPixels)); + m_uploadUpdateRect = IntRect(); m_dirtyRect.setSize(FloatSize()); // Large layers always stay dirty, because they need to update when the content rect changes. m_contentsDirty = requiresClippedUpdateRect(); @@ -339,43 +246,59 @@ void ContentLayerChromium::draw() ASSERT(layerRenderer()); - const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const ContentLayerChromium::Program* program = layerRenderer()->contentLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); bindContentsTexture(); - layerRenderer()->useShader(sv->contentShaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); if (requiresClippedUpdateRect()) { - float m43 = drawTransform().m43(); + float m43 = ccLayerImpl()->drawTransform().m43(); TransformationMatrix transform; transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), transform, m_visibleRectInLayerCoords.width(), - m_visibleRectInLayerCoords.height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); + m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } else { drawTexturedQuad(context, layerRenderer()->projectionMatrix(), - drawTransform(), m_bounds.width(), m_bounds.height(), - drawOpacity(), sv->shaderMatrixLocation(), - sv->shaderAlphaLocation()); + ccLayerImpl()->drawTransform(), bounds().width(), bounds().height(), + ccLayerImpl()->drawOpacity(), program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } unreserveContentsTexture(); } void ContentLayerChromium::unreserveContentsTexture() { - if (m_contentsTexture) + if (!m_skipsDraw && m_contentsTexture) m_contentsTexture->unreserve(); } void ContentLayerChromium::bindContentsTexture() { - if (m_contentsTexture) + updateTextureIfNeeded(); + + if (!m_skipsDraw && m_contentsTexture) m_contentsTexture->bindTexture(); } +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void ContentLayerChromium::dumpLayerProperties(TextStream& ts, int indent) const +{ + LayerChromium::dumpLayerProperties(ts, indent); + writeIndent(ts, indent); + ts << "skipsDraw: " << m_skipsDraw << "\n"; +} } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h index 3363518..6f070c2 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h @@ -35,6 +35,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "LayerChromium.h" +#include "PlatformCanvas.h" #include "TextureManager.h" namespace WebCore { @@ -54,43 +55,31 @@ public: virtual void bindContentsTexture(); virtual void draw(); - virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); } - - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned contentShaderProgram() const { return m_contentShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - int initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_contentShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - int m_initialized; - }; + virtual bool drawsContent() const { return m_owner && m_owner->drawsContent(); } + + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderTexAlpha> Program; protected: explicit ContentLayerChromium(GraphicsLayerChromium* owner); - void updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect); - virtual void cleanupResources(); bool requiresClippedUpdateRect() const; + void resizeUploadBuffer(const IntSize&); + + virtual const char* layerTypeAsString() const { return "ContentLayer"; } + virtual void dumpLayerProperties(TextStream&, int indent) const; OwnPtr<LayerTexture> m_contentsTexture; bool m_skipsDraw; + // The portion of the upload buffer that has a pending update, in the coordinates of the texture. + IntRect m_uploadUpdateRect; + + virtual void updateTextureIfNeeded(); + void updateTexture(const uint8_t* pixels, const IntSize&); + private: + PlatformCanvas m_canvas; IntRect m_visibleRectInLayerCoords; FloatPoint m_layerCenterInSurfaceCoords; diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h index 92fb7b3..3b0fdbf 100644 --- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h +++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h @@ -46,6 +46,10 @@ public: virtual int getGraphicsResetStatusARB(); virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); enum { // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp index a849a6c..bbe6d62 100644 --- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp @@ -43,6 +43,7 @@ #include "SkTypeface.h" #include "SkUtils.h" +#include <unicode/locid.h> #include <wtf/Assertions.h> #include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> @@ -57,7 +58,8 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { - String family = PlatformBridge::getFontFamilyForCharacters(characters, length); + icu::Locale locale = icu::Locale::getDefault(); + String family = PlatformBridge::getFontFamilyForCharacters(characters, length, locale.getLanguage()); if (family.isEmpty()) return 0; diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp index 953ee2f..2ff6b8b 100644 --- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp +++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp @@ -38,10 +38,12 @@ #include "GraphicsContext3D.h" #include "internal_glu.h" #include "IntRect.h" +#include "LoopBlinnPathProcessor.h" +#include "LoopBlinnSolidFillShader.h" #include "Path.h" #include "PlatformString.h" #include "SharedGraphicsContext3D.h" -#if PLATFORM(SKIA) +#if USE(SKIA) #include "SkPath.h" #endif #include "Texture.h" @@ -170,6 +172,7 @@ GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawin , m_context(context) , m_drawingBuffer(drawingBuffer) , m_state(0) + , m_pathVertexBuffer(0) { m_flipMatrix.translate(-1.0f, 1.0f); m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height()); @@ -191,7 +194,7 @@ void GLES2Canvas::clearRect(const FloatRect& rect) { bindFramebuffer(); if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) { - m_context->scissor(rect); + m_context->scissor(rect.x(), m_size.height() - rect.height() - rect.y(), rect.width(), rect.height()); m_context->enable(GraphicsContext3D::SCISSOR_TEST); m_context->clearColor(Color(RGBA32(0))); m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); @@ -263,6 +266,11 @@ void GLES2Canvas::concatCTM(const AffineTransform& affine) m_state->m_ctm *= affine; } +void GLES2Canvas::setCTM(const AffineTransform& affine) +{ + m_state->m_ctm = affine; +} + void GLES2Canvas::clipPath(const Path& path) { bindFramebuffer(); @@ -396,9 +404,9 @@ Texture* GLES2Canvas::getTexture(NativeImagePtr ptr) return m_context->getTexture(ptr); } -#if PLATFORM(SKIA) +#if USE(SKIA) // This is actually cross-platform code, but since its only caller is inside a -// PLATFORM(SKIA), it will cause a warning-as-error on Chrome/Mac. +// USE(SKIA), it will cause a warning-as-error on Chrome/Mac. static void interpolateQuadratic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2) { float tIncrement = 1.0f / pathTesselation, t = tIncrement; @@ -473,7 +481,7 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig checkGLError("createVertexBufferFromPath, createBuffer"); DoubleVector inVertices; WTF::Vector<size_t> contours; -#if PLATFORM(SKIA) +#if USE(SKIA) const SkPath* skPath = path.platformPath(); SkPoint pts[4]; SkPath::Iter iter(*skPath, true); @@ -548,28 +556,61 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig void GLES2Canvas::fillPath(const Path& path, const Color& color) { - int count; - unsigned vertexBuffer, indexBuffer; - createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer); - m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer); - checkGLError("bindBuffer"); - m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer); - checkGLError("bindBuffer"); + if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) { + bindFramebuffer(); + m_context->applyCompositeOperator(m_state->m_compositeOp); + + m_pathCache.clear(); + LoopBlinnPathProcessor processor; + processor.process(path, m_pathCache); + if (!m_pathVertexBuffer) + m_pathVertexBuffer = m_context->createBuffer(); + m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer); + int byteSizeOfVertices = 2 * m_pathCache.numberOfVertices() * sizeof(float); + int byteSizeOfTexCoords = 3 * m_pathCache.numberOfVertices() * sizeof(float); + int byteSizeOfInteriorVertices = 2 * m_pathCache.numberOfInteriorVertices() * sizeof(float); + m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, + byteSizeOfVertices + byteSizeOfTexCoords + byteSizeOfInteriorVertices, + GraphicsContext3D::STATIC_DRAW); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, byteSizeOfVertices, m_pathCache.vertices()); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices, byteSizeOfTexCoords, m_pathCache.texcoords()); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices + byteSizeOfTexCoords, byteSizeOfInteriorVertices, m_pathCache.interiorVertices()); + + AffineTransform matrix(m_flipMatrix); + matrix *= m_state->m_ctm; + + // Draw the exterior + m_context->useLoopBlinnExteriorProgram(0, byteSizeOfVertices, matrix, color); + m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfVertices()); + + // Draw the interior + m_context->useLoopBlinnInteriorProgram(byteSizeOfVertices + byteSizeOfTexCoords, matrix, color); + m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfInteriorVertices()); + } else { + int count; + unsigned vertexBuffer, indexBuffer; + createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer); + m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer); + checkGLError("bindBuffer"); + m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer); + checkGLError("bindBuffer"); - AffineTransform matrix(m_flipMatrix); - matrix *= m_state->m_ctm; + AffineTransform matrix(m_flipMatrix); + matrix *= m_state->m_ctm; - m_context->useFillSolidProgram(matrix, color); - checkGLError("useFillSolidProgram"); + m_context->useFillSolidProgram(matrix, color); + checkGLError("useFillSolidProgram"); - m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0); - checkGLError("drawArrays"); + bindFramebuffer(); + m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0); + checkGLError("drawArrays"); - m_context->graphicsContext3D()->deleteBuffer(vertexBuffer); - checkGLError("deleteBuffer"); + m_context->graphicsContext3D()->deleteBuffer(vertexBuffer); + checkGLError("deleteBuffer"); - m_context->graphicsContext3D()->deleteBuffer(indexBuffer); - checkGLError("deleteBuffer"); + m_context->graphicsContext3D()->deleteBuffer(indexBuffer); + checkGLError("deleteBuffer"); + } } void GLES2Canvas::beginStencilDraw() diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h index 605f86f..8887a16 100644 --- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h +++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h @@ -36,6 +36,7 @@ #include "ColorSpace.h" #include "GraphicsTypes.h" #include "ImageSource.h" +#include "LoopBlinnPathCache.h" #include "Texture.h" #include <wtf/HashMap.h> @@ -68,6 +69,7 @@ public: void rotate(float angleInRadians); void scale(const FloatSize&); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); void clipPath(const Path&); void clipOut(const Path&); @@ -113,6 +115,10 @@ private: StateVector m_stateStack; State* m_state; AffineTransform m_flipMatrix; + + // Members for GPU-accelerated path rendering. + LoopBlinnPathCache m_pathCache; + unsigned m_pathVertexBuffer; }; } diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp new file mode 100644 index 0000000..a859aae --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 "GeometryBinding.h" + +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" +#include "LayerRendererChromium.h" + +namespace WebCore { + +GeometryBinding::GeometryBinding(GraphicsContext3D* context) + : m_context(context) + , m_quadVerticesVbo(0) + , m_quadElementsVbo(0) + , m_initialized(false) +{ + // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad. + float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; + uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. + 0, 1, 2, 3}; // A line path for drawing the layer border. + + GLC(m_context, m_quadVerticesVbo = m_context->createBuffer()); + GLC(m_context, m_quadElementsVbo = m_context->createBuffer()); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW)); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW)); + + m_initialized = true; +} + +GeometryBinding::~GeometryBinding() +{ + GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo)); + GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo)); +} + +void GeometryBinding::prepareForDraw() +{ + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, quadVerticesVbo())); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, quadElementsVbo())); + unsigned offset = 0; + GLC(m_context, m_context->vertexAttribPointer(positionAttribLocation(), 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + offset += 3 * sizeof(float); + GLC(m_context, m_context->vertexAttribPointer(texCoordAttribLocation(), 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + GLC(m_context, m_context->enableVertexAttribArray(positionAttribLocation())); + GLC(m_context, m_context->enableVertexAttribArray(texCoordAttribLocation())); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.h b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h new file mode 100644 index 0000000..ec19970 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 GeometryBinding_h +#define GeometryBinding_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +namespace WebCore { + +class GraphicsContext3D; + +class GeometryBinding { +public: + explicit GeometryBinding(GraphicsContext3D*); + ~GeometryBinding(); + + bool initialized() const { return m_initialized; } + + GraphicsContext3D* context() const { return m_context; } + unsigned quadVerticesVbo() const { return m_quadVerticesVbo; } + unsigned quadElementsVbo() const { return m_quadElementsVbo; } + + void prepareForDraw(); + + // All layer shaders share the same attribute locations for the vertex + // positions and texture coordinates. This allows switching shaders without + // rebinding attribute arrays. + static int positionAttribLocation() { return 0; } + static int texCoordAttribLocation() { return 1; } + +private: + GraphicsContext3D* m_context; + unsigned m_quadVerticesVbo; + unsigned m_quadElementsVbo; + bool m_initialized; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp index 488230c..067c54d 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp @@ -111,8 +111,20 @@ GraphicsLayerChromium::~GraphicsLayerChromium() void GraphicsLayerChromium::setName(const String& inName) { + m_nameBase = inName; String name = String::format("GraphicsLayerChromium(%p) GraphicsLayer(%p) ", m_layer.get(), this) + inName; GraphicsLayer::setName(name); + updateNames(); +} + +void GraphicsLayerChromium::updateNames() +{ + if (m_layer) + m_layer->setName("Layer for " + m_nameBase); + if (m_transformLayer) + m_transformLayer->setName("TransformLayer for " + m_nameBase); + if (m_contentsLayer) + m_contentsLayer->setName("ContentsLayer for " + m_nameBase); } bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children) @@ -590,6 +602,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D() } updateOpacityOnLayer(); + updateNames(); } void GraphicsLayerChromium::updateLayerDrawsContent() @@ -653,6 +666,7 @@ void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer) } } updateDebugIndicators(); + updateNames(); } // This function simply mimics the operation of GraphicsLayerCA diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h index 92c61fe..db8c6f7 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h @@ -107,6 +107,7 @@ private: LayerChromium* hostLayerForSublayers() const; LayerChromium* layerForSuperlayer() const; + void updateNames(); void updateSublayerList(); void updateLayerPosition(); void updateLayerSize(); @@ -127,6 +128,8 @@ private: void setupContentsLayer(LayerChromium*); LayerChromium* contentsLayer() const { return m_contentsLayer.get(); } + String m_nameBase; + RefPtr<LayerChromium> m_layer; RefPtr<LayerChromium> m_transformLayer; RefPtr<LayerChromium> m_contentsLayer; diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp index cd299c1..7c42366 100644 --- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp @@ -38,18 +38,6 @@ #include "LayerRendererChromium.h" #include "LayerTexture.h" -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#endif - -#if PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#include <CoreGraphics/CGContext.h> -#include <CoreGraphics/CGImage.h> -#include <wtf/RetainPtr.h> -#endif - namespace WebCore { PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium* owner) @@ -84,80 +72,17 @@ void ImageLayerChromium::updateContentsIfDirty() return; } - void* pixels = 0; - IntSize bitmapSize; - - NativeImagePtr nativeImage = m_contents->nativeImageForCurrentFrame(); - -#if PLATFORM(SKIA) - // The layer contains an Image. - NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage); - const SkBitmap* skiaBitmap = skiaImage; - bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height()); - ASSERT(skiaBitmap); -#elif PLATFORM(CG) - // NativeImagePtr is a CGImageRef on Mac OS X. - int width = CGImageGetWidth(nativeImage); - int height = CGImageGetHeight(nativeImage); - bitmapSize = IntSize(width, height); -#endif - - // Clip the dirty rect to the bitmap dimensions. - IntRect dirtyRect(m_dirtyRect); - dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize)); + m_decodedImage.updateFromImage(m_contents->nativeImageForCurrentFrame()); +} - if (!m_contentsTexture || !m_contentsTexture->isValid(bitmapSize, GraphicsContext3D::RGBA)) - dirtyRect = IntRect(IntPoint(0, 0), bitmapSize); - else if (!m_contentsDirty) { - m_contentsTexture->reserve(bitmapSize, GraphicsContext3D::RGBA); +void ImageLayerChromium::updateTextureIfNeeded() +{ + // FIXME: Remove this test when tiled layers are implemented. + if (requiresClippedUpdateRect()) { + ContentLayerChromium::updateTextureIfNeeded(); return; } - -#if PLATFORM(SKIA) - SkAutoLockPixels lock(*skiaBitmap); - SkBitmap::Config skiaConfig = skiaBitmap->config(); - // FIXME: do we need to support more image configurations? - if (skiaConfig == SkBitmap::kARGB_8888_Config) - pixels = skiaBitmap->getPixels(); -#elif PLATFORM(CG) - // FIXME: we should get rid of this temporary copy where possible. - int tempRowBytes = width * 4; - Vector<uint8_t> tempVector; - tempVector.resize(height * tempRowBytes); - // Note we do not zero this vector since we are going to - // completely overwrite its contents with the image below. - // Try to reuse the color space from the image to preserve its colors. - // Some images use a color space (such as indexed) unsupported by the bitmap context. - RetainPtr<CGColorSpaceRef> colorSpaceReleaser; - CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage); - CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); - switch (colorSpaceModel) { - case kCGColorSpaceModelMonochrome: - case kCGColorSpaceModelRGB: - case kCGColorSpaceModelCMYK: - case kCGColorSpaceModelLab: - case kCGColorSpaceModelDeviceN: - break; - default: - colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB()); - colorSpace = colorSpaceReleaser.get(); - break; - } - RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(), - width, height, 8, tempRowBytes, - colorSpace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy); - CGContextDrawImage(tempContext.get(), - CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), - nativeImage); - pixels = tempVector.data(); -#else -#error "Need to implement for your platform." -#endif - - if (pixels) - updateTextureRect(pixels, bitmapSize, dirtyRect); + updateTexture(m_decodedImage.pixels(), m_decodedImage.size()); } } diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h index a5c1450..cc9064d 100644 --- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h @@ -35,6 +35,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "ContentLayerChromium.h" +#include "PlatformImage.h" #if PLATFORM(CG) #include <wtf/RetainPtr.h> @@ -50,13 +51,19 @@ public: static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0); virtual void updateContentsIfDirty(); - virtual bool drawsContent() { return m_contents; } + virtual bool drawsContent() const { return m_contents; } void setContents(Image* image); +protected: + virtual const char* layerTypeAsString() const { return "ImageLayer"; } + private: + virtual void updateTextureIfNeeded(); + ImageLayerChromium(GraphicsLayerChromium* owner); + PlatformImage m_decodedImage; RefPtr<Image> m_contents; }; diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp index 8d01d9b..95b7386 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -34,106 +34,24 @@ #include "LayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" -#if PLATFORM(SKIA) +#if USE(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" #endif #include "RenderLayerBacking.h" +#include "TextStream.h" #include "skia/ext/platform_canvas.h" -#include <wtf/text/WTFString.h> namespace WebCore { using namespace std; -const unsigned LayerChromium::s_positionAttribLocation = 0; -const unsigned LayerChromium::s_texCoordAttribLocation = 1; - -static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource) -{ - unsigned shader = context->createShader(type); - if (!shader) - return 0; - String sourceString(shaderSource); - GLC(context, context->shaderSource(shader, sourceString)); - GLC(context, context->compileShader(shader)); - int compiled = 0; - GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled)); - if (!compiled) { - GLC(context, context->deleteShader(shader)); - return 0; - } - return shader; -} - -LayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_quadVerticesVbo(0) - , m_quadElementsVbo(0) - , m_maxTextureSize(0) - , m_borderShaderProgram(0) - , m_borderShaderMatrixLocation(-1) - , m_borderShaderColorLocation(-1) - , m_initialized(false) -{ - // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad. - float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; - uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. - 0, 1, 2, 3}; // A line path for drawing the layer border. - - GLC(m_context, m_quadVerticesVbo = m_context->createBuffer()); - GLC(m_context, m_quadElementsVbo = m_context->createBuffer()); - GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo)); - GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW)); - GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); - GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW)); - - // Get the max texture size supported by the system. - GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize)); - - // Shaders for drawing the debug borders around the layers. - char borderVertexShaderString[] = - "attribute vec4 a_position; \n" - "uniform mat4 matrix; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - "} \n"; - char borderFragmentShaderString[] = - "precision mediump float; \n" - "uniform vec4 color; \n" - "void main() \n" - "{ \n" - " gl_FragColor = vec4(color.xyz * color.w, color.w);\n" - "} \n"; - - m_borderShaderProgram = createShaderProgram(m_context, borderVertexShaderString, borderFragmentShaderString); - if (!m_borderShaderProgram) { - LOG_ERROR("ContentLayerChromium: Failed to create shader program"); - return; - } - - m_borderShaderMatrixLocation = m_context->getUniformLocation(m_borderShaderProgram, "matrix"); - m_borderShaderColorLocation = m_context->getUniformLocation(m_borderShaderProgram, "color"); - ASSERT(m_borderShaderMatrixLocation != -1); - ASSERT(m_borderShaderColorLocation != -1); - - m_initialized = true; -} - -LayerChromium::SharedValues::~SharedValues() -{ - GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo)); - GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo)); - if (m_borderShaderProgram) - GLC(m_context, m_context->deleteProgram(m_borderShaderProgram)); -} - +#ifndef NDEBUG +static int s_nextLayerDebugID = 1; +#endif PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner) { @@ -144,25 +62,22 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner) : m_owner(owner) , m_contentsDirty(false) , m_maskLayer(0) - , m_targetRenderSurface(0) , m_superlayer(0) +#ifndef NDEBUG + , m_debugID(s_nextLayerDebugID++) +#endif , m_anchorPoint(0.5, 0.5) , m_backgroundColor(0, 0, 0, 0) - , m_borderColor(0, 0, 0, 0) , m_opacity(1.0) , m_zPosition(0.0) , m_anchorPointZ(0) - , m_borderWidth(0) , m_clearsContext(false) - , m_doubleSided(true) , m_hidden(false) , m_masksToBounds(false) , m_opaque(true) , m_geometryFlipped(false) , m_needsDisplayOnBoundsChange(false) - , m_drawDepth(0) - , m_layerRenderer(0) - , m_renderSurface(0) + , m_ccLayerImpl(CCLayerImpl::create(this)) , m_replicaLayer(0) { } @@ -179,8 +94,7 @@ LayerChromium::~LayerChromium() void LayerChromium::cleanupResources() { - if (m_renderSurface) - m_renderSurface->cleanupResources(); + m_ccLayerImpl->cleanupResources(); } void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) @@ -192,55 +106,7 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) setNeedsDisplay(); } - m_layerRenderer = renderer; -} - -RenderSurfaceChromium* LayerChromium::createRenderSurface() -{ - m_renderSurface = new RenderSurfaceChromium(this); - return m_renderSurface.get(); -} - -unsigned LayerChromium::createShaderProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource) -{ - unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); - if (!vertexShader) { - LOG_ERROR("Failed to create vertex shader"); - return 0; - } - - unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); - if (!fragmentShader) { - GLC(context, context->deleteShader(vertexShader)); - LOG_ERROR("Failed to create fragment shader"); - return 0; - } - - unsigned programObject = context->createProgram(); - if (!programObject) { - LOG_ERROR("Failed to create shader program"); - return 0; - } - - GLC(context, context->attachShader(programObject, vertexShader)); - GLC(context, context->attachShader(programObject, fragmentShader)); - - // Bind the common attrib locations. - GLC(context, context->bindAttribLocation(programObject, s_positionAttribLocation, "a_position")); - GLC(context, context->bindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord")); - - GLC(context, context->linkProgram(programObject)); - int linked = 0; - GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); - if (!linked) { - LOG_ERROR("Failed to link shader program"); - GLC(context, context->deleteProgram(programObject)); - return 0; - } - - GLC(context, context->deleteShader(vertexShader)); - GLC(context, context->deleteShader(fragmentShader)); - return programObject; + m_ccLayerImpl->setLayerRenderer(renderer); } void LayerChromium::setNeedsCommit() @@ -317,16 +183,15 @@ int LayerChromium::indexOfSublayer(const LayerChromium* reference) void LayerChromium::setBounds(const IntSize& size) { - if (m_bounds == size) + if (bounds() == size) return; - bool firstResize = !m_bounds.width() && !m_bounds.height() && size.width() && size.height(); + bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height(); - m_bounds = size; - m_backingStoreSize = size; + m_ccLayerImpl->setBounds(size); if (firstResize) - setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); + setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height())); else setNeedsCommit(); } @@ -337,7 +202,7 @@ void LayerChromium::setFrame(const FloatRect& rect) return; m_frame = rect; - setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); + setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height())); } const LayerChromium* LayerChromium::rootLayer() const @@ -372,6 +237,12 @@ LayerChromium* LayerChromium::superlayer() const return m_superlayer; } +void LayerChromium::setName(const String& name) +{ + m_name = name; + m_ccLayerImpl->setName(name); +} + void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect) { // Simply mark the contents as dirty. For non-root layers, the call to @@ -386,7 +257,7 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect) void LayerChromium::setNeedsDisplay() { m_dirtyRect.setLocation(FloatPoint()); - m_dirtyRect.setSize(m_bounds); + m_dirtyRect.setSize(bounds()); m_contentsDirty = true; setNeedsCommit(); } @@ -445,38 +316,7 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); } -void LayerChromium::drawDebugBorder() -{ - static float glMatrix[16]; - if (!borderColor().alpha()) - return; - - ASSERT(layerRenderer()); - const SharedValues* sv = layerRenderer()->layerSharedValues(); - ASSERT(sv && sv->initialized()); - layerRenderer()->useShader(sv->borderShaderProgram()); - TransformationMatrix renderMatrix = drawTransform(); - renderMatrix.scale3d(bounds().width(), bounds().height(), 1); - toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); - GraphicsContext3D* context = layerRendererContext(); - GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1)); - - GLC(context, context->uniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1)); - GLC(context, context->lineWidth(borderWidth())); - - // The indices for the line are stored in the same array as the triangle indices. - GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); -} - -const IntRect LayerChromium::getDrawRect() const -{ - // Form the matrix used by the shader to map the corners of the layer's - // bounds into the view space. - FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height()); - IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect)); - return mappedRect; -} // Returns true if any of the layer's descendants has drawable content. bool LayerChromium::descendantsDrawContent() @@ -501,19 +341,92 @@ bool LayerChromium::descendantsDrawContentRecursive() return false; } -// static -void LayerChromium::prepareForDraw(const SharedValues* sv) +String LayerChromium::layerTreeAsText() const +{ + TextStream ts; + dumpLayer(ts, 0); + return ts.release(); +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void LayerChromium::dumpLayer(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << layerTypeAsString() << "(" << m_name << ")\n"; + dumpLayerProperties(ts, indent+2); + m_ccLayerImpl->dumpLayerProperties(ts, indent+2); + if (m_replicaLayer) { + writeIndent(ts, indent+2); + ts << "Replica:\n"; + m_replicaLayer->dumpLayer(ts, indent+3); + } + if (m_maskLayer) { + writeIndent(ts, indent+2); + ts << "Mask:\n"; + m_maskLayer->dumpLayer(ts, indent+3); + } + for (size_t i = 0; i < m_sublayers.size(); ++i) + m_sublayers[i]->dumpLayer(ts, indent+1); +} + +void LayerChromium::dumpLayerProperties(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); +#ifndef NDEBUG + ts << "debugID: " << debugID() << ", "; +#else +#endif + ts << "drawsContent: " << drawsContent() << "\n"; + +} + +// Begin calls that forward to the CCLayerImpl. +// ============================================== +// These exists just for debugging (via drawDebugBorder()). +void LayerChromium::setBorderColor(const Color& color) +{ + m_ccLayerImpl->setDebugBorderColor(color); + setNeedsCommit(); +} + +Color LayerChromium::borderColor() const +{ + return m_ccLayerImpl->debugBorderColor(); +} + +void LayerChromium::setBorderWidth(float width) +{ + m_ccLayerImpl->setDebugBorderWidth(width); + setNeedsCommit(); +} + +float LayerChromium::borderWidth() const +{ + return m_ccLayerImpl->debugBorderWidth(); +} + +LayerRendererChromium* LayerChromium::layerRenderer() const +{ + return m_ccLayerImpl->layerRenderer(); +} + +void LayerChromium::setDoubleSided(bool doubleSided) +{ + m_ccLayerImpl->setDoubleSided(doubleSided); + setNeedsCommit(); +} + +const IntSize& LayerChromium::bounds() const { - GraphicsContext3D* context = sv->context(); - GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, sv->quadVerticesVbo())); - GLC(context, context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo())); - unsigned offset = 0; - GLC(context, context->vertexAttribPointer(s_positionAttribLocation, 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); - offset += 3 * sizeof(float); - GLC(context, context->vertexAttribPointer(s_texCoordAttribLocation, 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); - GLC(context, context->enableVertexAttribArray(s_positionAttribLocation)); - GLC(context, context->enableVertexAttribArray(s_texCoordAttribLocation)); + return m_ccLayerImpl->bounds(); } +// ============================================== +// End calls that forward to the CCLayerImpl. } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h index 5c7e2b1..29a2165 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h @@ -38,13 +38,17 @@ #include "GraphicsContext.h" #include "GraphicsLayerChromium.h" #include "PlatformString.h" +#include "ProgramBinding.h" #include "RenderSurfaceChromium.h" +#include "ShaderChromium.h" #include "TransformationMatrix.h" + #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> #include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> namespace skia { @@ -53,13 +57,13 @@ class PlatformCanvas; namespace WebCore { +class CCLayerImpl; class GraphicsContext3D; class LayerRendererChromium; // Base class for composited layers. Special layer types are derived from // this class. class LayerChromium : public RefCounted<LayerChromium> { - friend class LayerRendererChromium; friend class LayerTilerChromium; public: static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0); @@ -85,21 +89,9 @@ public: void setBackgroundColor(const Color& color) { m_backgroundColor = color; setNeedsCommit(); } Color backgroundColor() const { return m_backgroundColor; } - void setBorderColor(const Color& color) { m_borderColor = color; setNeedsCommit(); } - Color borderColor() const { return m_borderColor; } - - void setBorderWidth(float width) { m_borderWidth = width; setNeedsCommit(); } - float borderWidth() const { return m_borderWidth; } - - void setBounds(const IntSize&); - IntSize bounds() const { return m_bounds; } - void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); } bool clearsContext() const { return m_clearsContext; } - void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); } - bool doubleSided() const { return m_doubleSided; } - void setFrame(const FloatRect&); FloatRect frame() const { return m_frame; } @@ -109,10 +101,11 @@ public: void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; } bool masksToBounds() const { return m_masksToBounds; } - void setName(const String& name) { m_name = name; } - String name() const { return m_name; } + void setName(const String&); + const String& name() const { return m_name; } void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; } + CCLayerImpl* maskDrawLayer() const { return m_maskLayer ? m_maskLayer->ccLayerImpl() : 0; } LayerChromium* maskLayer() const { return m_maskLayer.get(); } void setNeedsDisplay(const FloatRect& dirtyRect); @@ -144,75 +137,60 @@ public: void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); } bool geometryFlipped() const { return m_geometryFlipped; } - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - float drawOpacity() const { return m_drawOpacity; } - bool preserves3D() { return m_owner && m_owner->preserves3D(); } // Derived types must override this method if they need to react to a change // in the LayerRendererChromium. virtual void setLayerRenderer(LayerRendererChromium*); + // Returns true if any of the layer's descendants has content to draw. + bool descendantsDrawContent(); + void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; } void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; } LayerChromium* replicaLayer() { return m_replicaLayer; } - // Returns the rect containtaining this layer in the current view's coordinate system. - const IntRect getDrawRect() const; - // These methods typically need to be overwritten by derived classes. - virtual bool drawsContent() { return false; } + virtual bool drawsContent() const { return false; } virtual void updateContentsIfDirty() { } virtual void unreserveContentsTexture() { } virtual void bindContentsTexture() { } virtual void draw() { } + // These exists just for debugging (via drawDebugBorder()). + void setBorderColor(const Color&); + Color borderColor() const; + +#ifndef NDEBUG + int debugID() const { return m_debugID; } +#endif + void drawDebugBorder(); + String layerTreeAsText() const; + + void setBorderWidth(float); + float borderWidth() const; + + // Everything from here down in the public section will move to CCLayerImpl. - RenderSurfaceChromium* createRenderSurface(); - - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - GraphicsContext3D* context() const { return m_context; } - unsigned quadVerticesVbo() const { return m_quadVerticesVbo; } - unsigned quadElementsVbo() const { return m_quadElementsVbo; } - int maxTextureSize() const { return m_maxTextureSize; } - unsigned borderShaderProgram() const { return m_borderShaderProgram; } - int borderShaderMatrixLocation() const { return m_borderShaderMatrixLocation; } - int borderShaderColorLocation() const { return m_borderShaderColorLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_quadVerticesVbo; - unsigned m_quadElementsVbo; - int m_maxTextureSize; - unsigned m_borderShaderProgram; - int m_borderShaderMatrixLocation; - int m_borderShaderColorLocation; - bool m_initialized; - }; - - static void prepareForDraw(const SharedValues*); - - LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); } - - static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource); + CCLayerImpl* ccLayerImpl() const { return m_ccLayerImpl.get(); } static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix, float width, float height, float opacity, int matrixLocation, int alphaLocation); + // Begin calls that forward to the CCLayerImpl. + LayerRendererChromium* layerRenderer() const; + void setDoubleSided(bool); + void setBounds(const IntSize&); + const IntSize& bounds() const; + // End calls that forward to the CCLayerImpl. + + typedef ProgramBinding<VertexShaderPos, FragmentShaderColor> BorderProgram; protected: GraphicsLayerChromium* m_owner; - LayerChromium(GraphicsLayerChromium* owner); + explicit LayerChromium(GraphicsLayerChromium* owner); // This is called to clean up resources being held in the same context as // layerRendererContext(). Subclasses should override this method if they @@ -221,23 +199,18 @@ protected: GraphicsContext3D* layerRendererContext() const; - // Returns true if any of the layer's descendants has content to draw. - bool descendantsDrawContent(); - static void toGLMatrix(float*, const TransformationMatrix&); - IntSize m_bounds; + void dumpLayer(TextStream&, int indent) const; + + virtual const char* layerTypeAsString() const { return "LayerChromium"; } + virtual void dumpLayerProperties(TextStream&, int indent) const; + FloatRect m_dirtyRect; bool m_contentsDirty; RefPtr<LayerChromium> m_maskLayer; - // Render surface this layer draws into. This is a surface that can belong - // either to this layer (if m_targetRenderSurface == m_renderSurface) or - // to an ancestor of this layer. The target render surface determines the - // coordinate system the layer's transforms are relative to. - RenderSurfaceChromium* m_targetRenderSurface; - // All layer shaders share the same attribute locations for the vertex positions // and texture coordinates. This allows switching shaders without rebinding attribute // arrays. @@ -265,48 +238,30 @@ private: Vector<RefPtr<LayerChromium> > m_sublayers; LayerChromium* m_superlayer; +#ifndef NDEBUG + int m_debugID; +#endif + // Layer properties. - IntSize m_backingStoreSize; FloatPoint m_position; FloatPoint m_anchorPoint; Color m_backgroundColor; - Color m_borderColor; float m_opacity; float m_zPosition; float m_anchorPointZ; - float m_borderWidth; - float m_drawOpacity; bool m_clearsContext; - bool m_doubleSided; bool m_hidden; bool m_masksToBounds; bool m_opaque; bool m_geometryFlipped; bool m_needsDisplayOnBoundsChange; - // The global depth value of the center of the layer. This value is used - // to sort layers from back to front. - float m_drawDepth; - - // Points to the layer renderer that updates and draws this layer. - RefPtr<LayerRendererChromium> m_layerRenderer; - - FloatRect m_frame; TransformationMatrix m_transform; TransformationMatrix m_sublayerTransform; - TransformationMatrix m_drawTransform; - - // The scissor rectangle that should be used when this layer is drawn. - // Inherited by the parent layer and further restricted if this layer masks - // to bounds. - IntRect m_scissorRect; - // Render surface associated with this layer. The layer and its descendants - // will render to this surface. - OwnPtr<RenderSurfaceChromium> m_renderSurface; - - // Hierarchical bounding rect containing the layer and its descendants. - IntRect m_drawableContentRect; + FloatRect m_frame; + // For now, the LayerChromium directly owns its CCLayerImpl. + RefPtr<CCLayerImpl> m_ccLayerImpl; // Replica layer used for reflections. LayerChromium* m_replicaLayer; diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index f5548c9..e7b299f 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -34,14 +34,18 @@ #if USE(ACCELERATED_COMPOSITING) #include "LayerRendererChromium.h" +#include "cc/CCLayerImpl.h" #include "Canvas2DLayerChromium.h" +#include "GeometryBinding.h" #include "GraphicsContext3D.h" #include "LayerChromium.h" #include "LayerTexture.h" #include "NotImplemented.h" +#include "TextStream.h" #include "TextureManager.h" #include "WebGLLayerChromium.h" -#if PLATFORM(SKIA) +#include "cc/CCLayerImpl.h" +#if USE(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" #elif PLATFORM(CG) @@ -82,9 +86,9 @@ static bool isScaleOrTranslation(const TransformationMatrix& m) } -bool LayerRendererChromium::compareLayerZ(const LayerChromium* a, const LayerChromium* b) +bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImpl* b) { - return a->m_drawDepth < b->m_drawDepth; + return a->drawDepth() < b->drawDepth(); } PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context) @@ -100,9 +104,7 @@ PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<Graph } LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context) - : m_rootLayerTextureWidth(0) - , m_rootLayerTextureHeight(0) - , m_rootLayer(0) + : m_rootLayer(0) , m_scrollPosition(IntPoint(-1, -1)) , m_currentShader(0) , m_currentRenderSurface(0) @@ -112,12 +114,15 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte , m_defaultRenderSurface(0) { m_hardwareCompositing = initializeSharedObjects(); - m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256)); + m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels); ASSERT(m_rootLayerTiler); + + m_headsUpDisplay = CCHeadsUpDisplay::create(this); } LayerRendererChromium::~LayerRendererChromium() { + m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies. cleanupSharedObjects(); } @@ -172,71 +177,125 @@ void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, co } } -void LayerRendererChromium::updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect) +void LayerRendererChromium::updateRootLayerContents(TilePaintInterface& tilePaint, const IntRect& visibleRect) { m_rootLayerTiler->update(tilePaint, visibleRect); - m_rootLayerTiler->draw(visibleRect); +} +void LayerRendererChromium::updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect) +{ if (visibleRect.width() > contentRect.width()) { IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect); IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize)); if (!m_verticalScrollbarTiler) - m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize); + m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels); else m_verticalScrollbarTiler->setTileSize(tileSize); m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location()); m_verticalScrollbarTiler->update(scrollbarPaint, visibleRect); - m_verticalScrollbarTiler->draw(visibleRect); - } + } else + m_verticalScrollbarTiler.clear(); if (visibleRect.height() > contentRect.height()) { IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect); IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize)); if (!m_horizontalScrollbarTiler) - m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize); + m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels); else m_horizontalScrollbarTiler->setTileSize(tileSize); m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location()); m_horizontalScrollbarTiler->update(scrollbarPaint, visibleRect); - m_horizontalScrollbarTiler->draw(visibleRect); - } + } else + m_horizontalScrollbarTiler.clear(); +} + +void LayerRendererChromium::drawRootLayer() +{ + m_rootLayerTiler->draw(m_visibleRect); + + if (m_verticalScrollbarTiler) + m_verticalScrollbarTiler->draw(m_visibleRect); + + if (m_horizontalScrollbarTiler) + m_horizontalScrollbarTiler->draw(m_visibleRect); } -void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect, - const IntPoint& scrollPosition, TilePaintInterface& tilePaint, - TilePaintInterface& scrollbarPaint) +void LayerRendererChromium::updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint) { ASSERT(m_hardwareCompositing); if (!m_rootLayer) return; - makeContextCurrent(); + updateRootLayerContents(tilePaint, visibleRect); + // Recheck that we still have a root layer. This may become null if + // compositing gets turned off during a paint operation. + if (!m_rootLayer) + return; + + updateRootLayerScrollbars(scrollbarPaint, visibleRect, contentRect); + + Vector<CCLayerImpl*> renderSurfaceLayerList; + updateLayers(visibleRect, contentRect, scrollPosition, renderSurfaceLayerList); + + drawLayers(renderSurfaceLayerList); +} + +void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + Vector<CCLayerImpl*>& renderSurfaceLayerList) +{ + CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); + + if (!rootDrawLayer->renderSurface()) + rootDrawLayer->createRenderSurface(); + ASSERT(rootDrawLayer->renderSurface()); // If the size of the visible area has changed then allocate a new texture // to store the contents of the root layer and adjust the projection matrix // and viewport. - int visibleRectWidth = visibleRect.width(); - int visibleRectHeight = visibleRect.height(); - - if (!m_rootLayer->m_renderSurface) - m_rootLayer->createRenderSurface(); - m_rootLayer->m_renderSurface->m_contentRect = IntRect(0, 0, visibleRectWidth, visibleRectHeight); - if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) { - m_rootLayerTextureWidth = visibleRectWidth; - m_rootLayerTextureHeight = visibleRectHeight; + rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), visibleRect.size()); + if (visibleRect.size() != m_visibleRect.size()) { // Reset the current render surface to force an update of the viewport and // projection matrix next time useRenderSurface is called. m_currentRenderSurface = 0; } + m_visibleRect = visibleRect; + + m_scrollPosition = scrollPosition; + // Scissor out the scrollbars to avoid rendering on top of them. + IntRect rootScissorRect(contentRect); + // The scissorRect should not include the scroll offset. + rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y()); + rootDrawLayer->setScissorRect(rootScissorRect); + + m_defaultRenderSurface = rootDrawLayer->renderSurface(); + + renderSurfaceLayerList.append(rootDrawLayer); + + TransformationMatrix identityMatrix; + m_defaultRenderSurface->m_layerList.clear(); + // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state + // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw + // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the + // concept of a large content layer. + updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList); + + updateContentsRecursive(m_rootLayer.get()); +} + +void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList) +{ + CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); + makeContextCurrent(); // The GL viewport covers the entire visible area, including the scrollbars. - GLC(m_context.get(), m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight)); + GLC(m_context.get(), m_context->viewport(0, 0, m_visibleRect.width(), m_visibleRect.height())); // Bind the common vertex attributes used for drawing all the layers. - LayerChromium::prepareForDraw(layerSharedValues()); + m_sharedGeometry->prepareForDraw(); // FIXME: These calls can be made once, when the compositor context is initialized. GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST)); @@ -245,11 +304,6 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType. GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); - m_scrollPosition = scrollPosition; - - ASSERT(m_rootLayer->m_renderSurface); - m_defaultRenderSurface = m_rootLayer->m_renderSurface.get(); - useRenderSurface(m_defaultRenderSurface); // Clear to blue to make it easier to spot unrendered regions. @@ -260,66 +314,49 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect // zero alpha values on text glyphs. The root layer is always opaque. m_context->colorMask(true, true, true, false); - updateAndDrawRootLayer(tilePaint, scrollbarPaint, visibleRect, contentRect); + drawRootLayer(); // Re-enable color writes to layers, which may be partially transparent. m_context->colorMask(true, true, true, true); - // Recheck that we still have a root layer. This may become null if - // compositing gets turned off during a paint operation. - if (!m_rootLayer) - return; - - // Set the root visible/content rects --- used by subsequent drawLayers calls. - m_rootVisibleRect = visibleRect; - m_rootContentRect = contentRect; - - // Scissor out the scrollbars to avoid rendering on top of them. - IntRect rootScissorRect(contentRect); - // The scissorRect should not include the scroll offset. - rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y()); - m_rootLayer->m_scissorRect = rootScissorRect; - - Vector<LayerChromium*> renderSurfaceLayerList; - renderSurfaceLayerList.append(m_rootLayer.get()); - - TransformationMatrix identityMatrix; - m_defaultRenderSurface->m_layerList.clear(); - updateLayersRecursive(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList); - - // The shader used to render layers returns pre-multiplied alpha colors - // so we need to send the blending mode appropriately. GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); - GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); // Update the contents of the render surfaces. We traverse the array from // back to front to guarantee that nested render surfaces get rendered in the // correct order. for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { - LayerChromium* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; - ASSERT(renderSurfaceLayer->m_renderSurface); + CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; + ASSERT(renderSurfaceLayer->renderSurface()); // Render surfaces whose drawable area has zero width or height // will have no layers associated with them and should be skipped. - if (!renderSurfaceLayer->m_renderSurface->m_layerList.size()) + if (!renderSurfaceLayer->renderSurface()->m_layerList.size()) continue; - if (useRenderSurface(renderSurfaceLayer->m_renderSurface.get())) { - if (renderSurfaceLayer != m_rootLayer) { + if (useRenderSurface(renderSurfaceLayer->renderSurface())) { + if (renderSurfaceLayer != rootDrawLayer) { GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0)); GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); } - Vector<LayerChromium*>& layerList = renderSurfaceLayer->m_renderSurface->m_layerList; + Vector<CCLayerImpl*>& layerList = renderSurfaceLayer->renderSurface()->m_layerList; ASSERT(layerList.size()); for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) - drawLayer(layerList[layerIndex], renderSurfaceLayer->m_renderSurface.get()); + drawLayer(layerList[layerIndex], renderSurfaceLayer->renderSurface()); } } + if (m_headsUpDisplay->enabled()) { + GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); + GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); + GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); + useRenderSurface(m_defaultRenderSurface); + m_headsUpDisplay->draw(); + } + GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); } @@ -336,11 +373,15 @@ void LayerRendererChromium::present() // Note that currently this has the same effect as swapBuffers; we should // consider exposing a different entry point on GraphicsContext3D. m_context->prepareTexture(); + + m_headsUpDisplay->onPresent(); } void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; + if (m_rootLayer) + m_rootLayer->setLayerRenderer(this); m_rootLayerTiler->invalidateEntireLayer(); if (m_horizontalScrollbarTiler) m_horizontalScrollbarTiler->invalidateEntireLayer(); @@ -350,8 +391,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) { - ASSERT(rect.maxX() <= rootLayerTextureSize().width() - && rect.maxY() <= rootLayerTextureSize().height()); + ASSERT(rect.maxX() <= visibleRectSize().width() && rect.maxY() <= visibleRectSize().height()); if (!pixels) return; @@ -404,9 +444,10 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform // Recursively walks the layer tree starting at the given node and computes all the // necessary transformations, scissor rectangles, render surfaces, etc. -void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList) +void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList) { layer->setLayerRenderer(this); + CCLayerImpl* drawLayer = layer->ccLayerImpl(); // Compute the new matrix transformation that will be applied to this layer and // all its sublayers. It's important to remember that the layer's position @@ -459,25 +500,26 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // of their parent. bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform); bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D(); - bool useSurfaceForMasking = layer->maskLayer(); + bool useSurfaceForMasking = layer->maskDrawLayer(); bool useSurfaceForReflection = layer->replicaLayer(); if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent()) || useSurfaceForMasking || useSurfaceForReflection) { - RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get(); + RenderSurfaceChromium* renderSurface = drawLayer->renderSurface(); if (!renderSurface) - renderSurface = layer->createRenderSurface(); + renderSurface = drawLayer->createRenderSurface(); // The origin of the new surface is the upper left corner of the layer. - layer->m_drawTransform = TransformationMatrix(); - layer->m_drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0); + TransformationMatrix drawTransform; + drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0); + drawLayer->setDrawTransform(drawTransform); transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height()); // Layer's opacity will be applied when drawing the render surface. renderSurface->m_drawOpacity = layer->opacity(); - if (layer->superlayer()->preserves3D()) - renderSurface->m_drawOpacity *= layer->superlayer()->drawOpacity(); - layer->m_drawOpacity = 1; + if (layer->superlayer() && layer->superlayer()->preserves3D()) + renderSurface->m_drawOpacity *= drawLayer->superlayer()->drawOpacity(); + drawLayer->setDrawOpacity(1); TransformationMatrix layerOriginTransform = combinedTransform; layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0); @@ -485,69 +527,72 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr if (layerOriginTransform.isInvertible() && layer->superlayer()) { TransformationMatrix parentToLayer = layerOriginTransform.inverse(); - layer->m_scissorRect = parentToLayer.mapRect(layer->superlayer()->m_scissorRect); + drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect())); } else - layer->m_scissorRect = IntRect(); + drawLayer->setScissorRect(IntRect()); // The render surface scissor rect is the scissor rect that needs to // be applied before drawing the render surface onto its containing // surface and is therefore expressed in the superlayer's coordinate system. - renderSurface->m_scissorRect = layer->superlayer()->m_scissorRect; + renderSurface->m_scissorRect = drawLayer->superlayer() ? drawLayer->superlayer()->scissorRect() : drawLayer->scissorRect(); renderSurface->m_layerList.clear(); - if (layer->maskLayer()) { - renderSurface->m_maskLayer = layer->maskLayer(); - layer->maskLayer()->setLayerRenderer(this); - layer->maskLayer()->m_targetRenderSurface = renderSurface; + if (layer->maskDrawLayer()) { + renderSurface->m_maskLayer = layer->maskDrawLayer(); + layer->maskDrawLayer()->setLayerRenderer(this); + layer->maskDrawLayer()->setTargetRenderSurface(renderSurface); } else renderSurface->m_maskLayer = 0; - if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { - layer->replicaLayer()->maskLayer()->setLayerRenderer(this); - layer->replicaLayer()->maskLayer()->m_targetRenderSurface = renderSurface; + if (layer->replicaLayer() && layer->replicaLayer()->maskDrawLayer()) { + layer->replicaLayer()->maskDrawLayer()->setLayerRenderer(this); + layer->replicaLayer()->maskDrawLayer()->setTargetRenderSurface(renderSurface); } - renderSurfaceLayerList.append(layer); + renderSurfaceLayerList.append(drawLayer); } else { // DT = M[p] * LT - layer->m_drawTransform = combinedTransform; - transformedLayerRect = enclosingIntRect(layer->m_drawTransform.mapRect(layerRect)); + drawLayer->setDrawTransform(combinedTransform); + transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect)); - layer->m_drawOpacity = layer->opacity(); + drawLayer->setDrawOpacity(layer->opacity()); if (layer->superlayer()) { if (layer->superlayer()->preserves3D()) - layer->m_drawOpacity *= layer->superlayer()->m_drawOpacity; + drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity()); // Layers inherit the scissor rect from their superlayer. - layer->m_scissorRect = layer->superlayer()->m_scissorRect; + drawLayer->setScissorRect(drawLayer->superlayer()->scissorRect()); - layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface; + drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface()); } if (layer != m_rootLayer) - layer->m_renderSurface = 0; + drawLayer->clearRenderSurface(); - if (layer->masksToBounds()) - layer->m_scissorRect.intersect(transformedLayerRect); + if (layer->masksToBounds()) { + IntRect scissor = drawLayer->scissorRect(); + scissor.intersect(transformedLayerRect); + drawLayer->setScissorRect(scissor); + } } - if (layer->m_renderSurface) - layer->m_targetRenderSurface = layer->m_renderSurface.get(); + if (drawLayer->renderSurface()) + drawLayer->setTargetRenderSurface(drawLayer->renderSurface()); else { ASSERT(layer->superlayer()); - layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface; + drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface()); } - // m_drawableContentRect is always stored in the coordinate system of the + // drawableContentRect() is always stored in the coordinate system of the // RenderSurface the layer draws into. - if (layer->drawsContent()) - layer->m_drawableContentRect = transformedLayerRect; + if (drawLayer->drawsContent()) + drawLayer->setDrawableContentRect(transformedLayerRect); else - layer->m_drawableContentRect = IntRect(); + drawLayer->setDrawableContentRect(IntRect()); - TransformationMatrix sublayerMatrix = layer->m_drawTransform; + TransformationMatrix sublayerMatrix = drawLayer->drawTransform(); // Flatten to 2D if the layer doesn't preserve 3D. if (!layer->preserves3D()) { @@ -568,37 +613,46 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // M[s] = M * Tr[-center] sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0); - Vector<LayerChromium*>& descendants = (layer->m_renderSurface ? layer->m_renderSurface->m_layerList : layerList); - descendants.append(layer); + Vector<CCLayerImpl*>& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList); + descendants.append(drawLayer); unsigned thisLayerIndex = descendants.size() - 1; const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers(); for (size_t i = 0; i < sublayers.size(); ++i) { - LayerChromium* sublayer = sublayers[i].get(); - updateLayersRecursive(sublayer, sublayerMatrix, renderSurfaceLayerList, descendants); - - if (sublayer->m_renderSurface) { - RenderSurfaceChromium* sublayerRenderSurface = sublayer->m_renderSurface.get(); - layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect())); + CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl(); + updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants); + + if (sublayer->renderSurface()) { + RenderSurfaceChromium* sublayerRenderSurface = sublayer->renderSurface(); + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect())); + drawLayer->setDrawableContentRect(drawableContentRect); descendants.append(sublayer); - } else - layer->m_drawableContentRect.unite(sublayer->m_drawableContentRect); + } else { + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.unite(sublayer->drawableContentRect()); + drawLayer->setDrawableContentRect(drawableContentRect); + } } - if (layer->masksToBounds() || useSurfaceForMasking) - layer->m_drawableContentRect.intersect(transformedLayerRect); + if (layer->masksToBounds() || useSurfaceForMasking) { + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.intersect(transformedLayerRect); + drawLayer->setDrawableContentRect(drawableContentRect); + } - if (layer->m_renderSurface && layer != m_rootLayer) { - RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get(); - renderSurface->m_contentRect = layer->m_drawableContentRect; + if (drawLayer->renderSurface() && layer != m_rootLayer) { + RenderSurfaceChromium* renderSurface = drawLayer->renderSurface(); + renderSurface->m_contentRect = drawLayer->drawableContentRect(); FloatPoint surfaceCenter = renderSurface->contentRectCenter(); // Restrict the RenderSurface size to the portion that's visible. FloatSize centerOffsetDueToClipping; + // Don't clip if the layer is reflected as the reflection shouldn't be // clipped. if (!layer->replicaLayer()) { - renderSurface->m_contentRect.intersect(layer->m_scissorRect); + renderSurface->m_contentRect.intersect(drawLayer->scissorRect()); FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter(); centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter; } @@ -613,7 +667,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Since the layer starts a new render surface we need to adjust its // scissor rect to be expressed in the new surface's coordinate system. - layer->m_scissorRect = layer->m_drawableContentRect; + drawLayer->setScissorRect(drawLayer->drawableContentRect()); // Adjust the origin of the transform to be the center of the render surface. renderSurface->m_drawTransform = renderSurface->m_originTransform; @@ -631,14 +685,14 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Compute the depth value of the center of the layer which will be used when // sorting the layers for the preserves-3d property. - TransformationMatrix& layerDrawMatrix = layer->m_renderSurface ? layer->m_renderSurface->m_drawTransform : layer->m_drawTransform; + const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform(); if (layer->superlayer()) { if (!layer->superlayer()->preserves3D()) - layer->m_drawDepth = layer->superlayer()->m_drawDepth; + drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth()); else - layer->m_drawDepth = layerDrawMatrix.m43(); + drawLayer->setDrawDepth(layerDrawMatrix.m43()); } else - layer->m_drawDepth = 0; + drawLayer->setDrawDepth(0); // If preserves-3d then sort all the descendants by the Z coordinate of their // center. If the preserves-3d property is also set on the superlayer then @@ -647,21 +701,50 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ); } +void LayerRendererChromium::updateContentsRecursive(LayerChromium* layer) +{ + const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers(); + for (size_t i = 0; i < sublayers.size(); ++i) + updateContentsRecursive(sublayers[i].get()); + + if (layer->drawsContent()) + layer->updateContentsIfDirty(); + if (layer->maskLayer() && layer->maskLayer()->drawsContent()) + layer->maskLayer()->updateContentsIfDirty(); + if (layer->replicaLayer() && layer->replicaLayer()->drawsContent()) + layer->replicaLayer()->updateContentsIfDirty(); + if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent()) + layer->replicaLayer()->maskLayer()->updateContentsIfDirty(); +} + void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen) { + if (m_compositeOffscreen == compositeOffscreen) + return; + m_compositeOffscreen = compositeOffscreen; - if (!m_rootLayer) { - m_compositeOffscreen = false; - return; - } + if (!m_compositeOffscreen && m_rootLayer) + m_rootLayer->ccLayerImpl()->clearRenderSurface(); +} + +LayerTexture* LayerRendererChromium::getOffscreenLayerTexture() +{ + return m_compositeOffscreen ? m_rootLayer->ccLayerImpl()->renderSurface()->m_contentsTexture.get() : 0; +} +void LayerRendererChromium::copyOffscreenTextureToDisplay() +{ if (m_compositeOffscreen) { - // Need to explicitly set a LayerRendererChromium for the layer with the offscreen texture, - // or else the call to prepareContentsTexture() in useRenderSurface() will fail. - m_rootLayer->setLayerRenderer(this); - } else - m_rootLayer->m_renderSurface.clear(); + makeContextCurrent(); + + useRenderSurface(0); + m_defaultRenderSurface->m_drawTransform.makeIdentity(); + m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(), + 0.5 * m_defaultRenderSurface->m_contentRect.height(), 0); + m_defaultRenderSurface->m_drawOpacity = 1; + m_defaultRenderSurface->draw(); + } } bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurface) @@ -671,9 +754,12 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac m_currentRenderSurface = renderSurface; - if (renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) { + if ((renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) || (!renderSurface && m_compositeOffscreen)) { GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0)); - setDrawViewportRect(renderSurface->m_contentRect, true); + if (renderSurface) + setDrawViewportRect(renderSurface->m_contentRect, true); + else + setDrawViewportRect(m_defaultRenderSurface->m_contentRect, true); return true; } @@ -695,36 +781,32 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac return true; } -void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromium* targetSurface) +void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface) { - if (layer->m_renderSurface && layer->m_renderSurface != targetSurface) { - layer->m_renderSurface->draw(); + if (layer->renderSurface() && layer->renderSurface() != targetSurface) { + layer->renderSurface()->draw(); return; } - if (layer->m_bounds.isEmpty()) + if (layer->bounds().isEmpty()) return; - setScissorToRect(layer->m_scissorRect); + setScissorToRect(layer->scissorRect()); // Check if the layer falls within the visible bounds of the page. IntRect layerRect = layer->getDrawRect(); - bool isLayerVisible = layer->m_scissorRect.intersects(layerRect); + bool isLayerVisible = layer->scissorRect().intersects(layerRect); if (!isLayerVisible) return; // FIXME: Need to take into account the commulative render surface transforms all the way from // the default render surface in order to determine visibility. - TransformationMatrix combinedDrawMatrix = (layer->m_renderSurface ? layer->m_renderSurface->drawTransform().multiply(layer->m_drawTransform) : layer->m_drawTransform); + TransformationMatrix combinedDrawMatrix = (layer->renderSurface() ? layer->renderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform()); if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0) return; - if (layer->drawsContent()) { - // Update the contents of the layer if necessary. - layer->updateContentsIfDirty(); - m_context->makeContextCurrent(); + if (layer->drawsContent()) layer->draw(); - } // Draw the debug border if there is one. layer->drawDebugBorder(); @@ -734,9 +816,11 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromiu // scissorRect has its origin at the top left corner of the current visible rect. void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect) { + IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->m_contentRect : m_defaultRenderSurface->m_contentRect); + // The scissor coordinates must be supplied in viewport space so we need to offset // by the relative position of the top left corner of the current render surface. - int scissorX = scissorRect.x() - m_currentRenderSurface->m_contentRect.x(); + int scissorX = scissorRect.x() - contentRect.x(); // When rendering to the default render surface we're rendering upside down so the top // of the GL scissor is the bottom of our layer. // But, if rendering to offscreen texture, we reverse our sense of 'upside down'. @@ -744,7 +828,7 @@ void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect) if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen) scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y()); else - scissorY = scissorRect.y() - m_currentRenderSurface->m_contentRect.y(); + scissorY = scissorRect.y() - contentRect.y(); GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height())); } @@ -793,15 +877,23 @@ bool LayerRendererChromium::initializeSharedObjects() // Create an FBO for doing offscreen rendering. GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer()); - m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get())); - m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get())); - m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get())); - m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get())); - m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get())); - m_renderSurfaceSharedValues = adoptPtr(new RenderSurfaceChromium::SharedValues(m_context.get())); - - if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() - || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized() || !m_renderSurfaceSharedValues->initialized()) { + m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get())); + m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get())); + m_contentLayerProgram = adoptPtr(new ContentLayerChromium::Program(m_context.get())); + m_canvasLayerProgram = adoptPtr(new CanvasLayerChromium::Program(m_context.get())); + m_videoLayerRGBAProgram = adoptPtr(new VideoLayerChromium::RGBAProgram(m_context.get())); + m_videoLayerYUVProgram = adoptPtr(new VideoLayerChromium::YUVProgram(m_context.get())); + m_pluginLayerProgram = adoptPtr(new PluginLayerChromium::Program(m_context.get())); + m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get())); + m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get())); + m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get())); + + if (!m_sharedGeometry->initialized() || !m_borderProgram->initialized() + || !m_contentLayerProgram->initialized() || !m_canvasLayerProgram->initialized() + || !m_videoLayerRGBAProgram->initialized() || !m_videoLayerYUVProgram->initialized() + || !m_pluginLayerProgram->initialized() || !m_renderSurfaceProgram->initialized() + || !m_renderSurfaceMaskProgram->initialized() || !m_tilerProgram->initialized()) { + LOG_ERROR("Compositor failed to initialize shaders. Falling back to software."); cleanupSharedObjects(); return false; } @@ -814,12 +906,16 @@ void LayerRendererChromium::cleanupSharedObjects() { makeContextCurrent(); - m_layerSharedValues.clear(); - m_contentLayerSharedValues.clear(); - m_canvasLayerSharedValues.clear(); - m_videoLayerSharedValues.clear(); - m_pluginLayerSharedValues.clear(); - m_renderSurfaceSharedValues.clear(); + m_sharedGeometry.clear(); + m_borderProgram.clear(); + m_contentLayerProgram.clear(); + m_canvasLayerProgram.clear(); + m_videoLayerRGBAProgram.clear(); + m_videoLayerYUVProgram.clear(); + m_pluginLayerProgram.clear(); + m_renderSurfaceProgram.clear(); + m_renderSurfaceMaskProgram.clear(); + m_tilerProgram.clear(); if (m_offscreenFramebufferId) GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId)); @@ -831,6 +927,26 @@ void LayerRendererChromium::cleanupSharedObjects() m_textureManager.clear(); } +String LayerRendererChromium::layerTreeAsText() const +{ + TextStream ts; + if (m_rootLayer.get()) { + ts << m_rootLayer->layerTreeAsText(); + ts << "RenderSurfaces:\n"; + dumpRenderSurfaces(ts, 1, m_rootLayer.get()); + } + return ts.release(); +} + +void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const +{ + if (layer->ccLayerImpl()->renderSurface()) + layer->ccLayerImpl()->renderSurface()->dumpSurface(ts, indent); + + for (size_t i = 0; i < layer->getSublayers().size(); ++i) + dumpRenderSurfaces(ts, indent, layer->getSublayers()[i].get()); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h index 3d3e784..7e8850a 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -43,6 +43,7 @@ #include "RenderSurfaceChromium.h" #include "SkBitmap.h" #include "VideoLayerChromium.h" +#include "cc/CCHeadsUpDisplay.h" #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -57,7 +58,10 @@ namespace WebCore { +class CCLayerImpl; +class GeometryBinding; class GraphicsContext3D; +class CCHeadsUpDisplay; // Class that handles drawing of composited render layers using GL. class LayerRendererChromium : public RefCounted<LayerRendererChromium> { @@ -71,9 +75,8 @@ public: void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect); // updates and draws the current layers onto the backbuffer - void drawLayers(const IntRect& visibleRect, const IntRect& contentRect, - const IntPoint& scrollPosition, TilePaintInterface& tilePaint, - TilePaintInterface& scrollbarPaint); + void updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + TilePaintInterface&, TilePaintInterface& scrollbarPaint); // waits for rendering to finish void finish(); @@ -81,6 +84,8 @@ public: // puts backbuffer onscreen void present(); + IntSize visibleRectSize() const { return m_visibleRect.size(); } + void setRootLayer(PassRefPtr<LayerChromium> layer); LayerChromium* rootLayer() { return m_rootLayer.get(); } void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); } @@ -88,12 +93,9 @@ public: bool hardwareCompositing() const { return m_hardwareCompositing; } void setCompositeOffscreen(bool); - bool isCompositingOffscreen() { return m_compositeOffscreen; } - LayerTexture* getOffscreenLayerTexture() { return m_compositeOffscreen ? m_rootLayer->m_renderSurface->m_contentsTexture.get() : 0; } - - void setRootLayerCanvasSize(const IntSize&); - - GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); } + bool isCompositingOffscreen() const { return m_compositeOffscreen; } + LayerTexture* getOffscreenLayerTexture(); + void copyOffscreenTextureToDisplay(); unsigned createLayerTexture(); void deleteLayerTexture(unsigned); @@ -106,30 +108,43 @@ public: bool checkTextureSize(const IntSize&); - const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); } - const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); } - const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); } - const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); } - const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); } - const RenderSurfaceChromium::SharedValues* renderSurfaceSharedValues() const { return m_renderSurfaceSharedValues.get(); } + const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); } + const LayerChromium::BorderProgram* borderProgram() const { return m_borderProgram.get(); } + const ContentLayerChromium::Program* contentLayerProgram() const { return m_contentLayerProgram.get(); } + const CanvasLayerChromium::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); } + const VideoLayerChromium::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); } + const VideoLayerChromium::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); } + const PluginLayerChromium::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); } + const RenderSurfaceChromium::Program* renderSurfaceProgram() const { return m_renderSurfaceProgram.get(); } + const RenderSurfaceChromium::MaskProgram* renderSurfaceMaskProgram() const { return m_renderSurfaceMaskProgram.get(); } + const LayerTilerChromium::Program* tilerProgram() const { return m_tilerProgram.get(); } void resizeOnscreenContent(const IntSize&); - IntSize rootLayerTextureSize() const { return IntSize(m_rootLayerTextureWidth, m_rootLayerTextureHeight); } - IntRect rootLayerContentRect() const { return m_rootContentRect; } void getFramebufferPixels(void *pixels, const IntRect& rect); TextureManager* textureManager() const { return m_textureManager.get(); } + CCHeadsUpDisplay* headsUpDisplay() { return m_headsUpDisplay.get(); } + void setScissorToRect(const IntRect&); + String layerTreeAsText() const; + private: explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D); - void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList); - void drawLayer(LayerChromium*, RenderSurfaceChromium*); + void updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + Vector<CCLayerImpl*>& renderSurfaceLayerList); + void updateRootLayerContents(TilePaintInterface&, const IntRect& visibleRect); + void updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect); + void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList); + void updateContentsRecursive(LayerChromium*); - void updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect); + void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList); + void drawLayer(CCLayerImpl*, RenderSurfaceChromium*); + + void drawRootLayer(); bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect); @@ -139,7 +154,9 @@ private: bool makeContextCurrent(); - static bool compareLayerZ(const LayerChromium*, const LayerChromium*); + static bool compareLayerZ(const CCLayerImpl*, const CCLayerImpl*); + + void dumpRenderSurfaces(TextStream&, int indent, LayerChromium*) const; bool initializeSharedObjects(); void cleanupSharedObjects(); @@ -147,8 +164,7 @@ private: static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect); static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect); - int m_rootLayerTextureWidth; - int m_rootLayerTextureHeight; + IntRect m_visibleRect; TransformationMatrix m_projectionMatrix; @@ -166,7 +182,7 @@ private: unsigned m_offscreenFramebufferId; bool m_compositeOffscreen; -#if PLATFORM(SKIA) +#if USE(SKIA) OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas; OwnPtr<PlatformContextSkia> m_rootLayerSkiaContext; OwnPtr<GraphicsContext> m_rootLayerGraphicsContext; @@ -176,11 +192,6 @@ private: OwnPtr<GraphicsContext> m_rootLayerGraphicsContext; #endif - IntSize m_rootLayerCanvasSize; - - IntRect m_rootVisibleRect; - IntRect m_rootContentRect; - // Maximum texture dimensions supported. int m_maxTextureSize; @@ -188,15 +199,21 @@ private: // associated with this instance of the compositor. Since there can be // multiple instances of the compositor running in the same renderer process // we cannot store these values in static variables. - OwnPtr<LayerChromium::SharedValues> m_layerSharedValues; - OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues; - OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues; - OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues; - OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues; - OwnPtr<RenderSurfaceChromium::SharedValues> m_renderSurfaceSharedValues; + OwnPtr<GeometryBinding> m_sharedGeometry; + OwnPtr<LayerChromium::BorderProgram> m_borderProgram; + OwnPtr<ContentLayerChromium::Program> m_contentLayerProgram; + OwnPtr<CanvasLayerChromium::Program> m_canvasLayerProgram; + OwnPtr<VideoLayerChromium::RGBAProgram> m_videoLayerRGBAProgram; + OwnPtr<VideoLayerChromium::YUVProgram> m_videoLayerYUVProgram; + OwnPtr<PluginLayerChromium::Program> m_pluginLayerProgram; + OwnPtr<RenderSurfaceChromium::Program> m_renderSurfaceProgram; + OwnPtr<RenderSurfaceChromium::MaskProgram> m_renderSurfaceMaskProgram; + OwnPtr<LayerTilerChromium::Program> m_tilerProgram; OwnPtr<TextureManager> m_textureManager; + OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay; + RefPtr<GraphicsContext3D> m_context; RenderSurfaceChromium* m_defaultRenderSurface; diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index e28c084..86592a6 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -35,27 +35,23 @@ #include "LayerRendererChromium.h" #include "LayerTexture.h" -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#elif PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#endif - #include <wtf/PassOwnArrayPtr.h> +using namespace std; + namespace WebCore { -PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize) +PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border) { if (!layerRenderer || tileSize.isEmpty()) return 0; - return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize)); + return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize, border)); } -LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize) +LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border) : m_skipsDraw(false) + , m_tilingData(max(tileSize.width(), tileSize.height()), 0, 0, border == HasBorderTexels) , m_layerRenderer(layerRenderer) { setTileSize(tileSize); @@ -81,6 +77,7 @@ void LayerTilerChromium::setTileSize(const IntSize& size) m_tileSize = size; m_tilePixels = adoptArrayPtr(new uint8_t[m_tileSize.width() * m_tileSize.height() * 4]); + m_tilingData.setMaxTextureSize(max(size.width(), size.height())); } void LayerTilerChromium::reset() @@ -88,8 +85,7 @@ void LayerTilerChromium::reset() m_tiles.clear(); m_unusedTiles.clear(); - m_layerSize = IntSize(); - m_layerTileSize = IntSize(); + m_tilingData.setTotalSize(0, 0); m_lastUpdateLayerRect = IntRect(); } @@ -143,10 +139,10 @@ void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, in { const IntRect layerRect = contentRectToLayerRect(contentRect); - left = layerRect.x() / m_tileSize.width(); - top = layerRect.y() / m_tileSize.height(); - right = (layerRect.maxX() - 1) / m_tileSize.width(); - bottom = (layerRect.maxY() - 1) / m_tileSize.height(); + left = m_tilingData.tileXIndexFromSrcCoord(layerRect.x()); + top = m_tilingData.tileYIndexFromSrcCoord(layerRect.y()); + right = m_tilingData.tileXIndexFromSrcCoord(layerRect.maxX() - 1); + bottom = m_tilingData.tileYIndexFromSrcCoord(layerRect.maxY() - 1); } IntRect LayerTilerChromium::contentRectToLayerRect(const IntRect& contentRect) const @@ -169,22 +165,32 @@ IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) con int LayerTilerChromium::tileIndex(int i, int j) const { - ASSERT(i >= 0 && j >= 0 && i < m_layerTileSize.width() && j < m_layerTileSize.height()); - return i + j * m_layerTileSize.width(); + return m_tilingData.tileIndex(i, j); } IntRect LayerTilerChromium::tileContentRect(int i, int j) const { - IntPoint anchor(m_layerPosition.x() + i * m_tileSize.width(), m_layerPosition.y() + j * m_tileSize.height()); - IntRect tile(anchor, m_tileSize); - return tile; + IntRect contentRect = tileLayerRect(i, j); + contentRect.move(m_layerPosition.x(), m_layerPosition.y()); + return contentRect; } IntRect LayerTilerChromium::tileLayerRect(int i, int j) const { - IntPoint anchor(i * m_tileSize.width(), j * m_tileSize.height()); - IntRect tile(anchor, m_tileSize); - return tile; + const int index = m_tilingData.tileIndex(i, j); + IntRect layerRect = m_tilingData.tileBoundsWithBorder(index); + layerRect.setSize(m_tileSize); + return layerRect; +} + +IntSize LayerTilerChromium::layerSize() const +{ + return IntSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY()); +} + +IntSize LayerTilerChromium::layerTileSize() const +{ + return IntSize(m_tilingData.numTilesX(), m_tilingData.numTilesY()); } void LayerTilerChromium::invalidateRect(const IntRect& contentRect) @@ -220,8 +226,7 @@ void LayerTilerChromium::invalidateEntireLayer() } m_tiles.clear(); - m_layerSize = IntSize(); - m_layerTileSize = IntSize(); + m_tilingData.setTotalSize(0, 0); m_lastUpdateLayerRect = IntRect(); } @@ -258,55 +263,26 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont return; const IntRect paintRect = layerRectToContentRect(dirtyLayerRect); - GraphicsContext3D* context = layerRendererContext(); -#if PLATFORM(SKIA) - OwnPtr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas(paintRect.width(), paintRect.height(), false)); - OwnPtr<PlatformContextSkia> skiaContext(new PlatformContextSkia(canvas.get())); - OwnPtr<GraphicsContext> graphicsContext(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get()))); - - // Bring the canvas into the coordinate system of the paint rect. - canvas->translate(static_cast<SkScalar>(-paintRect.x()), static_cast<SkScalar>(-paintRect.y())); - painter.paint(*graphicsContext, paintRect); + m_canvas.resize(paintRect.size()); + PlatformCanvas::Painter canvasPainter(&m_canvas); + canvasPainter.context()->translate(-paintRect.x(), -paintRect.y()); + painter.paint(*canvasPainter.context(), paintRect); - // Get the contents of the updated rect. - const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); - ASSERT(bitmap.width() == paintRect.width() && bitmap.height() == paintRect.height()); - if (bitmap.width() != paintRect.width() || bitmap.height() != paintRect.height()) - CRASH(); - uint8_t* paintPixels = static_cast<uint8_t*>(bitmap.getPixels()); - if (!paintPixels) - CRASH(); -#elif PLATFORM(CG) - Vector<uint8_t> canvasPixels; - int rowBytes = 4 * paintRect.width(); - canvasPixels.resize(rowBytes * paintRect.height()); - memset(canvasPixels.data(), 0, canvasPixels.size()); - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); - RetainPtr<CGContextRef> m_cgContext; - m_cgContext.adoptCF(CGBitmapContextCreate(canvasPixels.data(), - paintRect.width(), paintRect.height(), 8, rowBytes, - colorSpace.get(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(m_cgContext.get(), 0, paintRect.height()); - CGContextScaleCTM(m_cgContext.get(), 1, -1); - OwnPtr<GraphicsContext> m_graphicsContext(new GraphicsContext(m_cgContext.get())); - - // Bring the CoreGraphics context into the coordinate system of the paint rect. - CGContextTranslateCTM(m_cgContext.get(), -paintRect.x(), -paintRect.y()); - painter.paint(*m_graphicsContext, paintRect); - - // Get the contents of the updated rect. - ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_cgContext.get())) == paintRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_cgContext.get())) == paintRect.height()); - uint8_t* paintPixels = static_cast<uint8_t*>(canvasPixels.data()); -#else -#error "Need to implement for your platform." -#endif + PlatformCanvas::AutoLocker locker(&m_canvas); + updateFromPixels(paintRect, locker.pixels()); +} +void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels) +{ // Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update. if (!m_tiles.size()) return; + GraphicsContext3D* context = layerRendererContext(); + + int left, top, right, bottom; + contentRectToTileIndices(paintRect, left, top, right, bottom); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { Tile* tile = m_tiles[tileIndex(i, j)].get(); @@ -346,7 +322,7 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont if (paintOffset.y() + destRect.height() > paintRect.height()) CRASH(); - uint8_t* pixelSource; + const uint8_t* pixelSource; if (paintRect.width() == sourceRect.width() && !paintOffset.x()) pixelSource = &paintPixels[4 * paintOffset.y() * paintRect.width()]; else { @@ -361,6 +337,9 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont } tile->texture()->bindTexture(); + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST)); + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST)); + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource)); tile->clearDirty(); @@ -378,26 +357,38 @@ void LayerTilerChromium::draw(const IntRect& contentRect) if (m_skipsDraw || !m_tiles.size()) return; - // We reuse the shader program used by ContentLayerChromium. GraphicsContext3D* context = layerRendererContext(); - const ContentLayerChromium::SharedValues* contentLayerValues = layerRenderer()->contentLayerSharedValues(); - layerRenderer()->useShader(contentLayerValues->contentShaderProgram()); - GLC(context, context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0)); + const LayerTilerChromium::Program* program = layerRenderer()->tilerProgram(); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); int left, top, right, bottom; contentRectToTileIndices(contentRect, left, top, right, bottom); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { - Tile* tile = m_tiles[tileIndex(i, j)].get(); + const int index = tileIndex(i, j); + Tile* tile = m_tiles[index].get(); ASSERT(tile); tile->texture()->bindTexture(); TransformationMatrix tileMatrix; - IntRect tileRect = tileContentRect(i, j); + + // Don't use tileContentRect here, as that contains the full + // rect with border texels which shouldn't be drawn. + IntRect tileRect = m_tilingData.tileBounds(index); + tileRect.move(m_layerPosition.x(), m_layerPosition.y()); tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0); - LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, m_tileSize.width(), m_tileSize.height(), 1, contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation()); + IntPoint texOffset = m_tilingData.textureOffset(i, j); + float tileWidth = static_cast<float>(m_tileSize.width()); + float tileHeight = static_cast<float>(m_tileSize.height()); + float texTranslateX = texOffset.x() / tileWidth; + float texTranslateY = texOffset.y() / tileHeight; + float texScaleX = tileRect.width() / tileWidth; + float texScaleY = tileRect.height() / tileHeight; + + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), 1, texTranslateX, texTranslateY, texScaleX, texScaleY, program); tile->texture()->unreserve(); } @@ -406,36 +397,63 @@ void LayerTilerChromium::draw(const IntRect& contentRect) void LayerTilerChromium::resizeLayer(const IntSize& size) { - if (m_layerSize == size) + if (layerSize() == size) return; - int width = (size.width() + m_tileSize.width() - 1) / m_tileSize.width(); - int height = (size.height() + m_tileSize.height() - 1) / m_tileSize.height(); + const IntSize oldTileSize = layerTileSize(); + m_tilingData.setTotalSize(size.width(), size.height()); + const IntSize newTileSize = layerTileSize(); + + if (oldTileSize == newTileSize) + return; - if (height && (width > INT_MAX / height)) + if (newTileSize.height() && (newTileSize.width() > INT_MAX / newTileSize.height())) CRASH(); Vector<OwnPtr<Tile> > newTiles; - newTiles.resize(width * height); - for (int j = 0; j < m_layerTileSize.height(); ++j) - for (int i = 0; i < m_layerTileSize.width(); ++i) - newTiles[i + j * width].swap(m_tiles[i + j * m_layerTileSize.width()]); - + newTiles.resize(newTileSize.width() * newTileSize.height()); + for (int j = 0; j < oldTileSize.height(); ++j) + for (int i = 0; i < oldTileSize.width(); ++i) + newTiles[i + j * newTileSize.width()].swap(m_tiles[i + j * oldTileSize.width()]); m_tiles.swap(newTiles); - m_layerSize = size; - m_layerTileSize = IntSize(width, height); } void LayerTilerChromium::growLayerToContain(const IntRect& contentRect) { // Grow the tile array to contain this content rect. IntRect layerRect = contentRectToLayerRect(contentRect); - IntSize layerSize = IntSize(layerRect.maxX(), layerRect.maxY()); + IntSize rectSize = IntSize(layerRect.maxX(), layerRect.maxY()); - IntSize newSize = layerSize.expandedTo(m_layerSize); + IntSize newSize = rectSize.expandedTo(layerSize()); resizeLayer(newSize); } +void LayerTilerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, + float width, float height, float opacity, + float texTranslateX, float texTranslateY, + float texScaleX, float texScaleY, + const LayerTilerChromium::Program* program) +{ + static float glMatrix[16]; + + TransformationMatrix renderMatrix = drawMatrix; + + // Apply a scaling factor to size the quad from 1x1 to its intended size. + renderMatrix.scale3d(width, height, 1); + + // Apply the projection matrix before sending the transform over to the shader. + LayerChromium::toGLMatrix(&glMatrix[0], projectionMatrix * renderMatrix); + + GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1)); + + GLC(context, context->uniform1f(program->fragmentShader().alphaLocation(), opacity)); + + GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), + texTranslateX, texTranslateY, texScaleX, texScaleY)); + + GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h index e09693d..bdb35a5 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h @@ -31,6 +31,8 @@ #include "LayerChromium.h" #include "LayerTexture.h" +#include "PlatformCanvas.h" +#include "TilingData.h" #include <wtf/OwnArrayPtr.h> namespace WebCore { @@ -46,13 +48,16 @@ public: class LayerTilerChromium { WTF_MAKE_NONCOPYABLE(LayerTilerChromium); public: - static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium* layerRenderer, const IntSize& tileSize); + enum BorderTexelOption { HasBorderTexels, NoBorderTexels }; + + static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption); ~LayerTilerChromium(); void invalidateRect(const IntRect& contentRect); void invalidateEntireLayer(); void update(TilePaintInterface& painter, const IntRect& contentRect); + void updateFromPixels(const IntRect& paintRect, const uint8_t* pixels); void draw(const IntRect& contentRect); // Set position of this tiled layer in content space. @@ -60,8 +65,10 @@ public: // Change the tile size. This may invalidate all the existing tiles. void setTileSize(const IntSize& size); + typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderTexAlpha> Program; + private: - LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize); + LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption); class Tile { WTF_MAKE_NONCOPYABLE(Tile); @@ -79,6 +86,12 @@ private: OwnPtr<LayerTexture> m_tex; }; + void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, + float width, float height, float opacity, + float texTranslateX, float texTranslateY, + float texScaleX, float texScaleY, + const LayerTilerChromium::Program*); + void resizeLayer(const IntSize& size); // Grow layer size to contain this rectangle. void growLayerToContain(const IntRect& contentRect); @@ -100,9 +113,10 @@ private: // Returns the bounds in layer space for a given tile location. IntRect tileLayerRect(int i, int j) const; + IntSize layerSize() const; + IntSize layerTileSize() const; + IntSize m_tileSize; - IntSize m_layerSize; - IntSize m_layerTileSize; IntRect m_lastUpdateLayerRect; IntPoint m_layerPosition; @@ -113,9 +127,13 @@ private: // Linear array of unused tiles. Vector<OwnPtr<Tile> > m_unusedTiles; + PlatformCanvas m_canvas; + // Cache a tile-sized pixel buffer to draw into. OwnArrayPtr<uint8_t> m_tilePixels; + TilingData m_tilingData; + LayerRendererChromium* m_layerRenderer; }; diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp new file mode 100644 index 0000000..29589f4 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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" + +#include "PlatformCanvas.h" + +#include "GraphicsContext.h" + +#if USE(SKIA) +#include "NativeImageSkia.h" +#include "PlatformContextSkia.h" +#include "SkColorPriv.h" +#include "skia/ext/platform_canvas.h" +#elif PLATFORM(CG) +#include <CoreGraphics/CGBitmapContext.h> +#endif + +namespace WebCore { + +PlatformCanvas::PlatformCanvas() +{ +} + +PlatformCanvas::~PlatformCanvas() +{ +} + +void PlatformCanvas::resize(const IntSize& size) +{ + m_size = size; +#if USE(SKIA) + m_skiaCanvas = new skia::PlatformCanvas(size.width(), size.height(), false); +#elif PLATFORM(CG) + size_t bufferSize = size.width() * size.height() * 4; + m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]); + memset(m_pixelData.get(), 0, bufferSize); +#endif +} + +PlatformCanvas::AutoLocker::AutoLocker(PlatformCanvas* canvas) + : m_canvas(canvas) + , m_pixels(0) +{ +#if USE(SKIA) + if (m_canvas->m_skiaCanvas) { + m_bitmap = &m_canvas->m_skiaCanvas->getDevice()->accessBitmap(false); + m_bitmap->lockPixels(); + + if (m_bitmap->config() == SkBitmap::kARGB_8888_Config) + m_pixels = static_cast<uint8_t*>(m_bitmap->getPixels()); + } else + m_bitmap = 0; +#elif PLATFORM(CG) + m_pixels = &canvas->m_pixelData[0]; +#endif +} + +PlatformCanvas::AutoLocker::~AutoLocker() +{ +#if USE(SKIA) + if (m_bitmap) + m_bitmap->unlockPixels(); +#endif +} + +PlatformCanvas::Painter::Painter(PlatformCanvas* canvas) +{ +#if USE(SKIA) + m_skiaContext = adoptPtr(new PlatformContextSkia(canvas->m_skiaCanvas.get())); + + // This is needed to get text to show up correctly. + m_skiaContext->setDrawingToImageBuffer(true); + + m_context = adoptPtr(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get()))); +#elif PLATFORM(CG) + + m_colorSpace = CGColorSpaceCreateDeviceRGB(); + size_t rowBytes = canvas->size().width() * 4; + m_contextCG = CGBitmapContextCreate(canvas->m_pixelData.get(), + canvas->size().width(), canvas->size().height(), 8, rowBytes, + m_colorSpace.get(), + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); + CGContextTranslateCTM(m_contextCG.get(), 0, canvas->size().height()); + CGContextScaleCTM(m_contextCG.get(), 1, -1); + m_context = adoptPtr(new GraphicsContext(m_contextCG.get())); +#endif +} + +PlatformCanvas::Painter::~Painter() +{ +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h new file mode 100644 index 0000000..262fdd0 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 PlatformCanvas_h +#define PlatformCanvas_h + +#include "IntSize.h" +#include <stdint.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +#if PLATFORM(CG) +#include <CoreGraphics/CGColorSpace.h> +#include <CoreGraphics/CGContext.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/RetainPtr.h> +#endif + +#if USE(SKIA) +namespace skia { class PlatformCanvas; } +class SkBitmap; +#endif + +namespace WebCore { + +class GraphicsContext; + +#if USE(SKIA) +class PlatformContextSkia; +#endif + +// A 2D buffer of pixels with an associated GraphicsContext. +class PlatformCanvas { + WTF_MAKE_NONCOPYABLE(PlatformCanvas); +public: + PlatformCanvas(); + ~PlatformCanvas(); + + // Scoped lock class to get temporary access to this canvas's pixels. + class AutoLocker { + WTF_MAKE_NONCOPYABLE(AutoLocker); + public: + explicit AutoLocker(PlatformCanvas*); + ~AutoLocker(); + + const uint8_t* pixels() const { return m_pixels; } + private: + PlatformCanvas* m_canvas; +#if USE(SKIA) + const SkBitmap* m_bitmap; +#endif + uint8_t* m_pixels; + }; + + // Scoped lock class to get temporary access to paint into this canvas. + class Painter { + WTF_MAKE_NONCOPYABLE(Painter); + public: + explicit Painter(PlatformCanvas*); + ~Painter(); + + GraphicsContext* context() const { return m_context.get(); } + private: + OwnPtr<GraphicsContext> m_context; +#if USE(SKIA) + OwnPtr<PlatformContextSkia> m_skiaContext; +#elif PLATFORM(CG) + RetainPtr<CGColorSpaceRef> m_colorSpace; + RetainPtr<CGContextRef> m_contextCG; +#endif + }; + + void resize(const IntSize&); + IntSize size() const { return m_size; } + +private: +#if USE(SKIA) + OwnPtr<skia::PlatformCanvas> m_skiaCanvas; +#elif PLATFORM(CG) + OwnArrayPtr<uint8_t> m_pixelData; +#endif + IntSize m_size; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp new file mode 100644 index 0000000..62cf4f8 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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" + +#include "PlatformImage.h" + +#if USE(SKIA) +#include "NativeImageSkia.h" +#include "PlatformContextSkia.h" +#elif PLATFORM(CG) +#include <CoreGraphics/CGBitmapContext.h> +#include <CoreGraphics/CGContext.h> +#include <CoreGraphics/CGImage.h> +#include <wtf/RetainPtr.h> +#else +#error "Need to implement for your platform" +#endif + +namespace WebCore { + +PlatformImage::PlatformImage() +{ +} + +void PlatformImage::updateFromImage(NativeImagePtr nativeImage) +{ +#if USE(SKIA) + // The layer contains an Image. + NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage); + const SkBitmap* skiaBitmap = skiaImage; + + IntSize bitmapSize(skiaBitmap->width(), skiaBitmap->height()); + ASSERT(skiaBitmap); +#elif PLATFORM(CG) + // NativeImagePtr is a CGImageRef on Mac OS X. + int width = CGImageGetWidth(nativeImage); + int height = CGImageGetHeight(nativeImage); + IntSize bitmapSize(width, height); +#endif + + size_t bufferSize = bitmapSize.width() * bitmapSize.height() * 4; + if (m_size != bitmapSize) { + m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]); + memset(m_pixelData.get(), 0, bufferSize); + m_size = bitmapSize; + } + +#if USE(SKIA) + SkAutoLockPixels lock(*skiaBitmap); + // FIXME: do we need to support more image configurations? + ASSERT(skiaBitmap->config()== SkBitmap::kARGB_8888_Config); + skiaBitmap->copyPixelsTo(m_pixelData.get(), bufferSize); +#elif PLATFORM(CG) + // FIXME: we should get rid of this temporary copy where possible. + int tempRowBytes = width * 4; + // Note we do not zero this vector since we are going to + // completely overwrite its contents with the image below. + // Try to reuse the color space from the image to preserve its colors. + // Some images use a color space (such as indexed) unsupported by the bitmap context. + RetainPtr<CGColorSpaceRef> colorSpaceReleaser; + CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage); + CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); + switch (colorSpaceModel) { + case kCGColorSpaceModelMonochrome: + case kCGColorSpaceModelRGB: + case kCGColorSpaceModelCMYK: + case kCGColorSpaceModelLab: + case kCGColorSpaceModelDeviceN: + break; + default: + colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB()); + colorSpace = colorSpaceReleaser.get(); + break; + } + RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(m_pixelData.get(), + width, height, 8, tempRowBytes, + colorSpace, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy); + CGContextDrawImage(tempContext.get(), + CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), + nativeImage); +#else +#error "Need to implement for your platform." +#endif +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.h b/Source/WebCore/platform/graphics/chromium/PlatformImage.h new file mode 100644 index 0000000..12f77b6 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 PlatformImage_h +#define PlatformImage_h + +#include "ImageSource.h" +#include "IntSize.h" +#include <stdint.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +class PlatformImage { + WTF_MAKE_NONCOPYABLE(PlatformImage); +public: + PlatformImage(); + + void updateFromImage(NativeImagePtr); + const uint8_t* pixels() const { return m_pixelData ? &m_pixelData[0] : 0; } + IntSize size() const { return m_size; } + +private: + OwnArrayPtr<uint8_t> m_pixelData; + IntSize m_size; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp index 878c142..5d595ad 100644 --- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp @@ -29,64 +29,13 @@ #include "PluginLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include <GLES2/gl2.h> namespace WebCore { -PluginLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_shaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_shaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_shaderProgram) { - LOG_ERROR("PluginLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -PluginLayerChromium::SharedValues::~SharedValues() -{ - if (m_shaderProgram) - GLC(m_context, m_context->deleteProgram(m_shaderProgram)); -} - PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromium* owner) { return adoptRef(new PluginLayerChromium(owner)); @@ -109,8 +58,8 @@ void PluginLayerChromium::updateContentsIfDirty() void PluginLayerChromium::draw() { ASSERT(layerRenderer()); - const PluginLayerChromium::SharedValues* sv = layerRenderer()->pluginLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const PluginLayerChromium::Program* program = layerRenderer()->pluginLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GL_TEXTURE0)); GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId)); @@ -122,11 +71,12 @@ void PluginLayerChromium::draw() GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - layerRenderer()->useShader(sv->shaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } } diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h index 853b328..8d66f5f 100644 --- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h @@ -37,31 +37,16 @@ namespace WebCore { class PluginLayerChromium : public LayerChromium { public: static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void updateContentsIfDirty(); virtual void draw(); void setTextureId(unsigned textureId); - class SharedValues { - public: - SharedValues(GraphicsContext3D* context); - ~SharedValues(); + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program; - unsigned shaderProgram() const { return m_shaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_shaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - bool m_initialized; - }; +protected: + virtual const char* layerTypeAsString() const { return "PluginLayer"; } private: PluginLayerChromium(GraphicsLayerChromium* owner); diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp new file mode 100644 index 0000000..6be00ef --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 "ProgramBinding.h" + +#include "GeometryBinding.h" +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" +#include "LayerRendererChromium.h" + +namespace WebCore { + +ProgramBindingBase::ProgramBindingBase(GraphicsContext3D* context) + : m_context(context) + , m_program(0) + , m_initialized(false) +{ +} + +ProgramBindingBase::~ProgramBindingBase() +{ + if (m_program) + GLC(m_context, m_context->deleteProgram(m_program)); +} + +bool ProgramBindingBase::init(const String& vertexShader, const String& fragmentShader) +{ + m_program = createShaderProgram(vertexShader, fragmentShader); + if (!m_program) { + LOG_ERROR("Failed to create shader program"); + return false; + } + return true; +} + +unsigned ProgramBindingBase::loadShader(unsigned type, const String& shaderSource) +{ + unsigned shader = m_context->createShader(type); + if (!shader) + return 0; + String sourceString(shaderSource); + GLC(m_context, m_context->shaderSource(shader, sourceString)); + GLC(m_context, m_context->compileShader(shader)); + int compiled = 0; + GLC(m_context, m_context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled)); + if (!compiled) { + GLC(m_context, m_context->deleteShader(shader)); + return 0; + } + return shader; +} + +unsigned ProgramBindingBase::createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource) +{ + unsigned vertexShader = loadShader(GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); + if (!vertexShader) { + LOG_ERROR("Failed to create vertex shader"); + return 0; + } + + unsigned fragmentShader = loadShader(GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); + if (!fragmentShader) { + GLC(m_context, m_context->deleteShader(vertexShader)); + LOG_ERROR("Failed to create fragment shader"); + return 0; + } + + unsigned programObject = m_context->createProgram(); + if (!programObject) { + LOG_ERROR("Failed to create shader program"); + return 0; + } + + GLC(m_context, m_context->attachShader(programObject, vertexShader)); + GLC(m_context, m_context->attachShader(programObject, fragmentShader)); + + // Bind the common attrib locations. + GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::positionAttribLocation(), "a_position")); + GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::texCoordAttribLocation(), "a_texCoord")); + + GLC(m_context, m_context->linkProgram(programObject)); + int linked = 0; + GLC(m_context, m_context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); + if (!linked) { + LOG_ERROR("Failed to link shader program"); + GLC(m_context, m_context->deleteProgram(programObject)); + return 0; + } + + GLC(m_context, m_context->deleteShader(vertexShader)); + GLC(m_context, m_context->deleteShader(fragmentShader)); + return programObject; +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.h b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h new file mode 100644 index 0000000..c6bf605 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 ProgramBinding_h +#define ProgramBinding_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +namespace WebCore { + +class GraphicsContext3D; + +class ProgramBindingBase { +public: + explicit ProgramBindingBase(GraphicsContext3D*); + ~ProgramBindingBase(); + + bool init(const String& vertexShader, const String& fragmentShader); + + unsigned program() const { return m_program; } + bool initialized() const { return m_initialized; } + +protected: + + unsigned loadShader(unsigned type, const String& shaderSource); + unsigned createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource); + + GraphicsContext3D* m_context; + unsigned m_program; + bool m_initialized; +}; + +template<class VertexShader, class FragmentShader> +class ProgramBinding : public ProgramBindingBase { +public: + explicit ProgramBinding(GraphicsContext3D* context) + : ProgramBindingBase(context) + { + if (!ProgramBindingBase::init(m_vertexShader.getShaderString(), m_fragmentShader.getShaderString())) + return; + if (!m_vertexShader.init(m_context, m_program)) + return; + if (!m_fragmentShader.init(m_context, m_program)) + return; + m_initialized = true; + } + + const VertexShader& vertexShader() const { return m_vertexShader; } + const FragmentShader& fragmentShader() const { return m_fragmentShader; } + +private: + + VertexShader m_vertexShader; + FragmentShader m_fragmentShader; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index b3ce9d7..ca42d0b 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -29,98 +29,17 @@ #include "RenderSurfaceChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" +#include "LayerChromium.h" #include "LayerRendererChromium.h" #include "LayerTexture.h" +#include "TextStream.h" +#include <wtf/text/CString.h> namespace WebCore { -RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_shaderProgram(0) - , m_maskShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_maskShaderSamplerLocation(-1) - , m_maskShaderMaskSamplerLocation(-1) - , m_maskShaderMatrixLocation(-1) - , m_maskShaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - char fragmentShaderWithMaskString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform sampler2D s_mask; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " vec4 maskColor = texture2D(s_mask, v_texCoord); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; \n" - "} \n"; - - m_shaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - m_maskShaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderWithMaskString); - if (!m_shaderProgram || !m_maskShaderProgram) { - LOG_ERROR("RenderSurfaceChromium: Failed to create shader program"); - return; - } - - GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture")); - GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix")); - GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha")); - - GLC(m_context, m_maskShaderSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_texture")); - GLC(m_context, m_maskShaderMaskSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_mask")); - GLC(m_context, m_maskShaderMatrixLocation = m_context->getUniformLocation(m_maskShaderProgram, "matrix")); - GLC(m_context, m_maskShaderAlphaLocation = m_context->getUniformLocation(m_maskShaderProgram, "alpha")); - - if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1 - || m_maskShaderSamplerLocation == -1 || m_maskShaderMaskSamplerLocation == -1 || m_maskShaderMatrixLocation == -1 || m_maskShaderAlphaLocation == -1) { - LOG_ERROR("Failed to initialize render surface shaders."); - return; - } - - GLC(m_context, m_context->useProgram(m_shaderProgram)); - GLC(m_context, m_context->uniform1i(m_shaderSamplerLocation, 0)); - GLC(m_context, m_context->useProgram(m_maskShaderProgram)); - GLC(m_context, m_context->uniform1i(m_maskShaderSamplerLocation, 0)); - GLC(m_context, m_context->uniform1i(m_maskShaderMaskSamplerLocation, 1)); - GLC(m_context, m_context->useProgram(0)); - m_initialized = true; -} - -RenderSurfaceChromium::SharedValues::~SharedValues() -{ - if (m_shaderProgram) - GLC(m_context, m_context->deleteProgram(m_shaderProgram)); - if (m_maskShaderProgram) - GLC(m_context, m_context->deleteProgram(m_maskShaderProgram)); -} - -RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer) +RenderSurfaceChromium::RenderSurfaceChromium(CCLayerImpl* owningLayer) : m_owningLayer(owningLayer) , m_maskLayer(0) , m_skipsDraw(false) @@ -179,36 +98,39 @@ bool RenderSurfaceChromium::prepareContentsTexture() return true; } -void RenderSurfaceChromium::drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform) +void RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform) { GraphicsContext3D* context3D = layerRenderer()->context(); int shaderMatrixLocation = -1; int shaderAlphaLocation = -1; - const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues(); - ASSERT(sv && sv->initialized()); + const RenderSurfaceChromium::Program* program = layerRenderer()->renderSurfaceProgram(); + const RenderSurfaceChromium::MaskProgram* maskProgram = layerRenderer()->renderSurfaceMaskProgram(); + ASSERT(program && program->initialized()); bool useMask = false; if (maskLayer && maskLayer->drawsContent()) { - maskLayer->updateContentsIfDirty(); if (!maskLayer->bounds().isEmpty()) { context3D->makeContextCurrent(); - layerRenderer()->useShader(sv->maskShaderProgram()); + layerRenderer()->useShader(maskProgram->program()); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); + GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().samplerLocation(), 0)); m_contentsTexture->bindTexture(); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); + GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().maskSamplerLocation(), 1)); maskLayer->bindContentsTexture(); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); - shaderMatrixLocation = sv->maskShaderMatrixLocation(); - shaderAlphaLocation = sv->maskShaderAlphaLocation(); + shaderMatrixLocation = maskProgram->vertexShader().matrixLocation(); + shaderAlphaLocation = maskProgram->fragmentShader().alphaLocation(); useMask = true; } } if (!useMask) { - layerRenderer()->useShader(sv->shaderProgram()); + layerRenderer()->useShader(program->program()); m_contentsTexture->bindTexture(); - shaderMatrixLocation = sv->shaderMatrixLocation(); - shaderAlphaLocation = sv->shaderAlphaLocation(); + GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0)); + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); } LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform, @@ -231,7 +153,7 @@ void RenderSurfaceChromium::draw() // both the layer and its reflection). The solution is to introduce yet another RenderSurface // to draw the layer and its reflection in. For now we only apply a separate reflection // mask if the contents don't have a mask of their own. - LayerChromium* replicaMaskLayer = m_maskLayer; + CCLayerImpl* replicaMaskLayer = m_maskLayer; if (!m_maskLayer && m_owningLayer->replicaLayer()) replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer(); @@ -244,5 +166,29 @@ void RenderSurfaceChromium::draw() drawSurface(m_maskLayer, m_drawTransform); } +String RenderSurfaceChromium::name() const +{ +#ifndef NDEBUG + return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->debugID(), m_owningLayer->name().utf8().data()); +#else + return String::format("RenderSurface(owner=%s)", m_owningLayer->name().utf8().data()); +#endif +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void RenderSurfaceChromium::dumpSurface(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << name() << "\n"; + + writeIndent(ts, indent+1); + ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n"; +} + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index b1f6a5c..6400c63 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -31,13 +31,15 @@ #include "FloatRect.h" #include "IntRect.h" +#include "ProgramBinding.h" +#include "ShaderChromium.h" #include "TextureManager.h" #include "TransformationMatrix.h" #include <wtf/Noncopyable.h> namespace WebCore { -class LayerChromium; +class CCLayerImpl; class LayerRendererChromium; class LayerTexture; @@ -45,13 +47,16 @@ class RenderSurfaceChromium { WTF_MAKE_NONCOPYABLE(RenderSurfaceChromium); friend class LayerRendererChromium; public: - explicit RenderSurfaceChromium(LayerChromium*); + explicit RenderSurfaceChromium(CCLayerImpl*); ~RenderSurfaceChromium(); bool prepareContentsTexture(); void cleanupResources(); void draw(); + String name() const; + void dumpSurface(TextStream&, int indent) const; + FloatPoint contentRectCenter() const { return FloatRect(m_contentRect).center(); } IntRect contentRect() const { return m_contentRect; } @@ -60,56 +65,26 @@ public: TransformationMatrix drawTransform() const { return m_drawTransform; } - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned shaderProgram() const { return m_shaderProgram; } - unsigned maskShaderProgram() const { return m_maskShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - int maskShaderSamplerLocation() const { return m_maskShaderSamplerLocation; } - int maskShaderMaskSamplerLocation() const { return m_maskShaderMaskSamplerLocation; } - int maskShaderMatrixLocation() const { return m_maskShaderMatrixLocation; } - int maskShaderAlphaLocation() const { return m_maskShaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - - unsigned m_shaderProgram; - unsigned m_maskShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - int m_maskShaderSamplerLocation; - int m_maskShaderMaskSamplerLocation; - int m_maskShaderMatrixLocation; - int m_maskShaderAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlpha> Program; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlphaMask> MaskProgram; private: LayerRendererChromium* layerRenderer(); - void drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform); + void drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform); - LayerChromium* m_owningLayer; - LayerChromium* m_maskLayer; + CCLayerImpl* m_owningLayer; + CCLayerImpl* m_maskLayer; IntRect m_contentRect; bool m_skipsDraw; + OwnPtr<LayerTexture> m_contentsTexture; float m_drawOpacity; TransformationMatrix m_drawTransform; TransformationMatrix m_replicaDrawTransform; TransformationMatrix m_originTransform; IntRect m_scissorRect; - Vector<LayerChromium*> m_layerList; + Vector<CCLayerImpl*> m_layerList; }; } diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp new file mode 100644 index 0000000..49b3462 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 "ShaderChromium.h" + +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" + +#define SHADER0(Src) #Src +#define SHADER(Src) SHADER0(Src) + +namespace WebCore { + +VertexShaderPosTex::VertexShaderPosTex() + : m_matrixLocation(-1) +{ +} + +bool VertexShaderPosTex::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + return m_matrixLocation != -1; +} + +String VertexShaderPosTex::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + varying vec2 v_texCoord; + void main() + { + gl_Position = matrix * a_position; + v_texCoord = a_texCoord; + } + ); +} + +VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch() + : m_matrixLocation(-1) + , m_yWidthScaleFactorLocation(-1) + , m_uvWidthScaleFactorLocation(-1) +{ +} + +bool VertexShaderPosTexYUVStretch::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_yWidthScaleFactorLocation = context->getUniformLocation(program, "y_widthScaleFactor"); + m_uvWidthScaleFactorLocation = context->getUniformLocation(program, "uv_widthScaleFactor"); + return m_matrixLocation != -1 && m_yWidthScaleFactorLocation != -1 && m_uvWidthScaleFactorLocation != -1; +} + +String VertexShaderPosTexYUVStretch::getShaderString() const +{ + return SHADER( + precision mediump float; + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + varying vec2 y_texCoord; + varying vec2 uv_texCoord; + uniform float y_widthScaleFactor; + uniform float uv_widthScaleFactor; + void main() + { + gl_Position = matrix * a_position; + y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x, a_texCoord.y); + uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x, a_texCoord.y); + } + ); +} + +VertexShaderPos::VertexShaderPos() + : m_matrixLocation(-1) +{ +} + +bool VertexShaderPos::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + return m_matrixLocation != -1; +} + +String VertexShaderPos::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + uniform mat4 matrix; + void main() + { + gl_Position = matrix * a_position; + } + ); +} + +VertexShaderPosTexTransform::VertexShaderPosTexTransform() + : m_matrixLocation(-1) + , m_texTransformLocation(-1) +{ +} + +bool VertexShaderPosTexTransform::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_texTransformLocation = context->getUniformLocation(program, "texTransform"); + return m_matrixLocation != -1 && m_texTransformLocation != -1; +} + +String VertexShaderPosTexTransform::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + uniform vec4 texTransform; + varying vec2 v_texCoord; + void main() + { + gl_Position = matrix * a_position; + v_texCoord = a_texCoord * texTransform.zw + texTransform.xy; + } + ); +} + +FragmentTexAlphaBinding::FragmentTexAlphaBinding() + : m_samplerLocation(-1) + , m_alphaLocation(-1) +{ +} + +bool FragmentTexAlphaBinding::init(GraphicsContext3D* context, unsigned program) +{ + m_samplerLocation = context->getUniformLocation(program, "s_texture"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + + return m_samplerLocation != -1 && m_alphaLocation != -1; +} + +String FragmentShaderRGBATexFlipAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); + gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; + } + ); +} + +String FragmentShaderRGBATexAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + gl_FragColor = texColor * alpha; + } + ); +} + +String FragmentShaderBGRATexAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; + } + ); +} + +FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask() + : m_samplerLocation(-1) + , m_maskSamplerLocation(-1) + , m_alphaLocation(-1) +{ +} + +bool FragmentShaderRGBATexAlphaMask::init(GraphicsContext3D* context, unsigned program) +{ + m_samplerLocation = context->getUniformLocation(program, "s_texture"); + m_maskSamplerLocation = context->getUniformLocation(program, "s_mask"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + + return m_samplerLocation != -1 && m_maskSamplerLocation != -1 && m_alphaLocation != -1; +} + +String FragmentShaderRGBATexAlphaMask::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform sampler2D s_mask; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + vec4 maskColor = texture2D(s_mask, v_texCoord); + gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; + } + ); +} + +FragmentShaderYUVVideo::FragmentShaderYUVVideo() + : m_yTextureLocation(-1) + , m_uTextureLocation(-1) + , m_vTextureLocation(-1) + , m_alphaLocation(-1) + , m_ccMatrixLocation(-1) + , m_signAdjLocation(-1) +{ +} + +bool FragmentShaderYUVVideo::init(GraphicsContext3D* context, unsigned program) +{ + m_yTextureLocation = context->getUniformLocation(program, "y_texture"); + m_uTextureLocation = context->getUniformLocation(program, "u_texture"); + m_vTextureLocation = context->getUniformLocation(program, "v_texture"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + m_ccMatrixLocation = context->getUniformLocation(program, "cc_matrix"); + m_signAdjLocation = context->getUniformLocation(program, "adj"); + + return m_yTextureLocation != -1 && m_uTextureLocation != -1 && m_vTextureLocation != -1 + && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_signAdjLocation != -1; +} + +String FragmentShaderYUVVideo::getShaderString() const +{ + return SHADER( + precision mediump float; + precision mediump int; + varying vec2 y_texCoord; + varying vec2 uv_texCoord; + uniform sampler2D y_texture; + uniform sampler2D u_texture; + uniform sampler2D v_texture; + uniform float alpha; + uniform float adj; + uniform mat3 cc_matrix; + void main() + { + float y = texture2D(y_texture, y_texCoord).x; + float u = texture2D(u_texture, uv_texCoord).x - adj; + float v = texture2D(v_texture, uv_texCoord).x - adj; + vec3 rgb = cc_matrix * vec3(y, u, v); + gl_FragColor = vec4(rgb, float(1)) * alpha; + } + ); +} + +FragmentShaderColor::FragmentShaderColor() + : m_colorLocation(-1) +{ +} + +bool FragmentShaderColor::init(GraphicsContext3D* context, unsigned program) +{ + m_colorLocation = context->getUniformLocation(program, "color"); + return m_colorLocation != -1; +} + +String FragmentShaderColor::getShaderString() const +{ + return SHADER( + precision mediump float; + uniform vec4 color; + void main() + { + gl_FragColor = vec4(color.xyz * color.w, color.w); + } + ); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h new file mode 100644 index 0000000..758c62b --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 ShaderChromium_h +#define ShaderChromium_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +#if USE(SKIA) +#include "SkColorPriv.h" +#endif + +namespace WebCore { + +class GraphicsContext3D; + +class VertexShaderPosTex { +public: + VertexShaderPosTex(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + +private: + int m_matrixLocation; +}; + +class VertexShaderPosTexYUVStretch { +public: + VertexShaderPosTexYUVStretch(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + int yWidthScaleFactorLocation() const { return m_yWidthScaleFactorLocation; } + int uvWidthScaleFactorLocation() const { return m_uvWidthScaleFactorLocation; } + +private: + int m_matrixLocation; + int m_yWidthScaleFactorLocation; + int m_uvWidthScaleFactorLocation; +}; + +class VertexShaderPos { +public: + VertexShaderPos(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + +private: + int m_matrixLocation; +}; + +class VertexShaderPosTexTransform { +public: + VertexShaderPosTexTransform(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + int texTransformLocation() const { return m_texTransformLocation; } + +private: + int m_matrixLocation; + int m_texTransformLocation; +}; + +class FragmentTexAlphaBinding { +public: + FragmentTexAlphaBinding(); + + bool init(GraphicsContext3D*, unsigned program); + int alphaLocation() const { return m_alphaLocation; } + int samplerLocation() const { return m_samplerLocation; } + +private: + int m_samplerLocation; + int m_alphaLocation; +}; + +class FragmentShaderRGBATexFlipAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderBGRATexAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderRGBATexAlphaMask { +public: + FragmentShaderRGBATexAlphaMask(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + int alphaLocation() const { return m_alphaLocation; } + int samplerLocation() const { return m_samplerLocation; } + int maskSamplerLocation() const { return m_maskSamplerLocation; } + +private: + int m_samplerLocation; + int m_maskSamplerLocation; + int m_alphaLocation; +}; + +#if USE(SKIA) && SK_B32_SHIFT +typedef FragmentShaderRGBATexAlpha FragmentShaderTexAlpha; +#else +typedef FragmentShaderBGRATexAlpha FragmentShaderTexAlpha; +#endif + +class FragmentShaderYUVVideo { +public: + FragmentShaderYUVVideo(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + + int yTextureLocation() const { return m_yTextureLocation; } + int uTextureLocation() const { return m_uTextureLocation; } + int vTextureLocation() const { return m_vTextureLocation; } + int alphaLocation() const { return m_alphaLocation; } + int ccMatrixLocation() const { return m_ccMatrixLocation; } + int signAdjLocation() const { return m_signAdjLocation; } + +private: + int m_yTextureLocation; + int m_uTextureLocation; + int m_vTextureLocation; + int m_alphaLocation; + int m_ccMatrixLocation; + int m_signAdjLocation; +}; + +class FragmentShaderColor { +public: + FragmentShaderColor(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + int colorLocation() const { return m_colorLocation; } + +private: + int m_colorLocation; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp index c4ad958..13cdb89 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp @@ -152,7 +152,7 @@ unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsign if (memoryRequiredBytes > m_memoryLimitBytes || !reduceMemoryToLimit(m_memoryLimitBytes - memoryRequiredBytes)) return 0; - unsigned textureId = m_context->createTexture(); + unsigned textureId; GLC(m_context.get(), textureId = m_context->createTexture()); GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); // Do basic linear filtering on resize. diff --git a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h index e176b0c..ab669d1 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h +++ b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h @@ -69,12 +69,15 @@ public: virtual SurfaceType surfaceType() const = 0; virtual Format format() const = 0; virtual unsigned width() const = 0; + virtual unsigned width(unsigned plane) const = 0; virtual unsigned height() const = 0; + virtual unsigned height(unsigned plane) const = 0; virtual unsigned planes() const = 0; virtual int stride(unsigned plane) const = 0; virtual const void* data(unsigned plane) const = 0; virtual unsigned texture(unsigned plane) const = 0; virtual const IntSize requiredTextureSize(unsigned plane) const = 0; + virtual bool hasPaddingBytes(unsigned plane) const = 0; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp index 41cd180..5d7a6e7 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp @@ -33,6 +33,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "VideoLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "Extensions3DChromium.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" @@ -51,125 +52,6 @@ const float VideoLayerChromium::yuv2RGB[9] = { 1.403f, -.714f, 0.f, }; -VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_yuvShaderProgram(0) - , m_rgbaShaderProgram(0) - , m_yuvShaderMatrixLocation(0) - , m_yuvWidthScaleFactorLocation(0) - , m_rgbaShaderMatrixLocation(0) - , m_rgbaWidthScaleFactorLocation(0) - , m_ccMatrixLocation(0) - , m_signAdjLocation(0) - , m_yTextureLocation(0) - , m_uTextureLocation(0) - , m_vTextureLocation(0) - , m_rgbaTextureLocation(0) - , m_yuvAlphaLocation(0) - , m_rgbaAlphaLocation(0) - , m_initialized(false) -{ - // Frame textures are allocated based on stride width, not visible frame - // width, such that there is a guarantee that the frame rows line up - // properly and are not shifted by (stride - width) pixels. To hide the - // "padding" pixels between the edge of the visible frame width and the end - // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much - // of the width of the texture should be shown when drawing the texture onto - // the vertices. - char vertexShaderString[] = - "precision mediump float; \n" - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "uniform float widthScaleFactor; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n" - "} \n"; - - char yuvFragmentShaderString[] = - "precision mediump float; \n" - "precision mediump int; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D y_texture; \n" - "uniform sampler2D u_texture; \n" - "uniform sampler2D v_texture; \n" - "uniform float alpha; \n" - "uniform float adj; \n" - "uniform mat3 cc_matrix; \n" - "void main() \n" - "{ \n" - " float y = texture2D(y_texture, v_texCoord).x; \n" - " float u = texture2D(u_texture, v_texCoord).x - adj; \n" - " float v = texture2D(v_texture, v_texCoord).x - adj; \n" - " vec3 rgb = cc_matrix * vec3(y, u, v); \n" - " gl_FragColor = vec4(rgb, float(1)) * alpha; \n" - "} \n"; - - char rgbaFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D rgba_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, float(1) - v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgbaFragmentShaderString); - if (!m_rgbaShaderProgram) { - LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program"); - return; - } - - m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvFragmentShaderString); - if (!m_yuvShaderProgram) { - LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program"); - return; - } - - m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "matrix"); - m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgram, "widthScaleFactor"); - m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_texture"); - m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture"); - m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture"); - m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix"); - m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj"); - m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha"); - - ASSERT(m_yuvShaderMatrixLocation != -1); - ASSERT(m_yuvWidthScaleFactorLocation != -1); - ASSERT(m_yTextureLocation != -1); - ASSERT(m_uTextureLocation != -1); - ASSERT(m_vTextureLocation != -1); - ASSERT(m_ccMatrixLocation != -1); - ASSERT(m_signAdjLocation != -1); - ASSERT(m_yuvAlphaLocation != -1); - - m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix"); - m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "rgba_texture"); - m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "widthScaleFactor"); - m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "alpha"); - - ASSERT(m_rgbaShaderMatrixLocation != -1); - ASSERT(m_rgbaTextureLocation != -1); - ASSERT(m_rgbaWidthScaleFactorLocation != -1); - ASSERT(m_rgbaAlphaLocation != -1); - - m_initialized = true; -} - -VideoLayerChromium::SharedValues::~SharedValues() -{ - if (m_yuvShaderProgram) - GLC(m_context, m_context->deleteProgram(m_yuvShaderProgram)); - if (m_rgbaShaderProgram) - GLC(m_context, m_context->deleteProgram(m_rgbaShaderProgram)); -} - PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner, VideoFrameProvider* provider) { @@ -297,9 +179,27 @@ bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, Vi if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) { allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat); m_textureSizes[plane] = planeTextureSize; - m_frameSizes[plane] = IntSize(frame->width(), frame->height()); + int frameWidth = frame->width(plane); + int frameHeight = frame->height(plane); + // When there are dead pixels at the edge of the texture, decrease + // the frame width by 1 to prevent the rightmost pixels from + // interpolating with the dead pixels. + if (frame->hasPaddingBytes(plane)) + --frameWidth; + m_frameSizes[plane] = IntSize(frameWidth, frameHeight); } } + + // In YV12, every 2x2 square of Y values corresponds to one U and + // one V value. If we decrease the width of the UV plane, we must decrease the + // width of the Y texture by 2 for proper alignment. This must happen + // always, even if Y's texture does not have padding bytes. + if (frame->format() == VideoFrameChromium::YV12) { + int yPlaneOriginalWidth = frame->width(VideoFrameChromium::yPlane); + if (frame->hasPaddingBytes(VideoFrameChromium::uPlane)) + m_frameSizes[VideoFrameChromium::yPlane].setWidth(yPlaneOriginalWidth - 2); + } + return true; } @@ -318,9 +218,10 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text memcpy(mem, data, dimensions.width() * dimensions.height()); GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem)); } else { - // FIXME: We should have some sort of code to handle the case when - // mapTexSubImage2D fails. - m_skipsDraw = true; + // If mapTexSubImage2DCHROMIUM fails, then do the slower texSubImage2D + // upload. This does twice the copies as mapTexSubImage2DCHROMIUM, one + // in the command buffer and another to the texture. + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, data)); } } @@ -330,16 +231,18 @@ void VideoLayerChromium::draw() return; ASSERT(layerRenderer()); - const VideoLayerChromium::SharedValues* sv = layerRenderer()->videoLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram(); + ASSERT(rgbaProgram && rgbaProgram->initialized()); + const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram(); + ASSERT(yuvProgram && yuvProgram->initialized()); switch (m_frameFormat) { case VideoFrameChromium::YV12: case VideoFrameChromium::YV16: - drawYUV(sv); + drawYUV(yuvProgram); break; case VideoFrameChromium::RGBA: - drawRGBA(sv); + drawRGBA(rgbaProgram); break; default: // FIXME: Implement other paths. @@ -359,7 +262,7 @@ void VideoLayerChromium::releaseCurrentFrame() resetFrameParameters(); } -void VideoLayerChromium::drawYUV(const SharedValues* sv) +void VideoLayerChromium::drawYUV(const VideoLayerChromium::YUVProgram* program) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); @@ -369,49 +272,57 @@ void VideoLayerChromium::drawYUV(const SharedValues* sv) GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane])); - layerRenderer()->useShader(sv->yuvShaderProgram()); - unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); - unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); - float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; - GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor)); + layerRenderer()->useShader(program->program()); + unsigned yFrameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); + unsigned yTextureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); + // Arbitrarily take the u sizes because u and v dimensions are identical. + unsigned uvFrameWidth = m_frameSizes[VideoFrameChromium::uPlane].width(); + unsigned uvTextureWidth = m_textureSizes[VideoFrameChromium::uPlane].width(); + + float yWidthScaleFactor = static_cast<float>(yFrameWidth) / yTextureWidth; + float uvWidthScaleFactor = static_cast<float>(uvFrameWidth) / uvTextureWidth; + GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor)); + GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor)); - GLC(context, context->uniform1i(sv->yTextureLocation(), 1)); - GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); - GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); + GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1)); + GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2)); + GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3)); // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion // formula to turn unsigned u and v values to signed u and v values. // This is loaded as a uniform because certain drivers have problems // reading literal float values. - GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5)); + GLC(context, context->uniform1f(program->fragmentShader().signAdjLocation(), 0.5)); - GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); + GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation()); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); // Reset active texture back to texture 0. GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); } -void VideoLayerChromium::drawRGBA(const SharedValues* sv) +void VideoLayerChromium::drawRGBA(const VideoLayerChromium::RGBAProgram* program) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane])); - layerRenderer()->useShader(sv->rgbaShaderProgram()); + layerRenderer()->useShader(program->program()); unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width(); unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width(); float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; - GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor)); + GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1)); - GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0)); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation()); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } void VideoLayerChromium::resetFrameParameters() diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h index ac3bca9..2170e13 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h @@ -46,53 +46,19 @@ public: VideoFrameProvider* = 0); virtual ~VideoLayerChromium(); virtual void updateContentsIfDirty(); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void draw(); // This function is called by VideoFrameProvider. When this method is called // putCurrentFrame() must be called to return the frame currently held. void releaseCurrentFrame(); - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - unsigned yuvShaderProgram() const { return m_yuvShaderProgram; } - unsigned rgbaShaderProgram() const { return m_rgbaShaderProgram; } - int yuvShaderMatrixLocation() const { return m_yuvShaderMatrixLocation; } - int rgbaShaderMatrixLocation() const { return m_rgbaShaderMatrixLocation; } - int yuvWidthScaleFactorLocation() const { return m_yuvWidthScaleFactorLocation; } - int rgbaWidthScaleFactorLocation() const { return m_rgbaWidthScaleFactorLocation; } - int yTextureLocation() const { return m_yTextureLocation; } - int uTextureLocation() const { return m_uTextureLocation; } - int vTextureLocation() const { return m_vTextureLocation; } - int yuvAlphaLocation() const { return m_yuvAlphaLocation; } - int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; } - int rgbaTextureLocation() const { return m_rgbaTextureLocation; } - int ccMatrixLocation() const { return m_ccMatrixLocation; } - int signAdjLocation() const { return m_signAdjLocation; } - bool initialized() const { return m_initialized; } - private: - GraphicsContext3D* m_context; - unsigned m_yuvShaderProgram; - unsigned m_rgbaShaderProgram; - int m_yuvShaderMatrixLocation; - int m_yuvWidthScaleFactorLocation; - int m_rgbaShaderMatrixLocation; - int m_rgbaWidthScaleFactorLocation; - int m_ccMatrixLocation; - int m_signAdjLocation; - int m_yTextureLocation; - int m_uTextureLocation; - int m_vTextureLocation; - int m_rgbaTextureLocation; - int m_yuvAlphaLocation; - int m_rgbaAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram; + typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram; protected: virtual void cleanupResources(); + virtual const char* layerTypeAsString() const { return "VideoLayer"; } private: VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*); @@ -103,8 +69,8 @@ private: void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*); void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat); void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data); - void drawYUV(const SharedValues*); - void drawRGBA(const SharedValues*); + void drawYUV(const YUVProgram*); + void drawRGBA(const RGBAProgram*); void resetFrameParameters(); void saveCurrentFrame(VideoFrameChromium*); diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp index 5b34bb9..e83d045 100644 --- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp @@ -82,6 +82,7 @@ void WebGLLayerChromium::setContext(const GraphicsContext3D* context) if (textureId != m_textureId) m_textureChanged = true; m_textureId = textureId; + m_premultipliedAlpha = m_context->getContextAttributes().premultipliedAlpha; } } diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h index c67cc2c..70be876 100644 --- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h @@ -44,11 +44,14 @@ class GraphicsContext3D; class WebGLLayerChromium : public CanvasLayerChromium { public: static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0); - virtual bool drawsContent() { return m_context; } + virtual bool drawsContent() const { return m_context; } virtual void updateContentsIfDirty(); void setContext(const GraphicsContext3D* context); +protected: + virtual const char* layerTypeAsString() const { return "WebGLLayer"; } + private: explicit WebGLLayerChromium(GraphicsLayerChromium* owner); GraphicsContext3D* m_context; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp new file mode 100644 index 0000000..604ef61 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 "CCHeadsUpDisplay.h" + +#include "CurrentTime.h" +#include "Font.h" +#include "FontDescription.h" +#include "GraphicsContext3D.h" +#include "LayerChromium.h" +#include "LayerTexture.h" +#include "TextRun.h" +#include "TextStream.h" +#include "TextureManager.h" +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +using namespace std; + +CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner) + : m_currentFrameNumber(0) + , m_layerRenderer(owner) + , m_showFPSCounter(false) + , m_showPlatformLayerTree(false) +{ + m_presentTimeHistoryInSec[0] = currentTime(); + m_presentTimeHistoryInSec[1] = m_presentTimeHistoryInSec[0]; +} + +CCHeadsUpDisplay::~CCHeadsUpDisplay() +{ +} + +void CCHeadsUpDisplay::draw() +{ + GraphicsContext3D* context = m_layerRenderer->context(); + if (!m_hudTexture) + m_hudTexture = LayerTexture::create(context, m_layerRenderer->textureManager()); + + // Use a fullscreen texture only if we need to... + IntSize hudSize; + if (m_showPlatformLayerTree) { + hudSize.setWidth(min(2048, m_layerRenderer->visibleRectSize().width())); + hudSize.setHeight(min(2048, m_layerRenderer->visibleRectSize().height())); + } else { + hudSize.setWidth(512); + hudSize.setHeight(128); + } + + m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA); + + // Render pixels into the texture. + PlatformCanvas canvas; + canvas.resize(hudSize); + { + PlatformCanvas::Painter painter(&canvas); + drawHudContents(painter.context(), hudSize); + } + + // Upload to GL. + { + PlatformCanvas::AutoLocker locker(&canvas); + + m_hudTexture->bindTexture(); + GLC(context.get(), context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels())); + } + + // Draw the HUD onto the default render surface. + const ContentLayerChromium::Program* program = m_layerRenderer->contentLayerProgram(); + ASSERT(program && program->initialized()); + GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); + m_hudTexture->bindTexture(); + m_layerRenderer->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + TransformationMatrix matrix; + matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0); + LayerChromium::drawTexturedQuad(context, m_layerRenderer->projectionMatrix(), + matrix, hudSize.width(), hudSize.height(), + 1.0f, program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); + + m_hudTexture->unreserve(); +} + +void CCHeadsUpDisplay::drawHudContents(GraphicsContext* ctx, const IntSize& hudSize) +{ + FontDescription mediumFontDesc; + mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily); + mediumFontDesc.setComputedSize(12); + Font mediumFont(mediumFontDesc, 0, 0); + mediumFont.update(0); + + FontDescription smallFontDesc; + smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily); + smallFontDesc.setComputedSize(10); + Font smallFont(smallFontDesc, 0, 0); + smallFont.update(0); + + // We haven't finished rendering yet, so we don't now the "current" present time. + // So, consider the *last two* present times and use those as our present time. + double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber - 1) % 2] - m_presentTimeHistoryInSec[m_currentFrameNumber % 2]; + + int y = 14; + + if (m_showPlatformLayerTree) { + ctx->setFillColor(Color(0, 0, 0, 192), ColorSpaceDeviceRGB); + ctx->fillRect(FloatRect(0, 0, hudSize.width(), hudSize.height())); + } + + // Draw fps. + String topLine = ""; + if (secForLastFrame > 0 && m_showFPSCounter) { + double fps = 1.0 / secForLastFrame; + topLine += String::format("FPS: %3.1f", fps); + } + if (topLine.length()) { + ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB); + TextRun run(topLine); + ctx->fillRect(FloatRect(2, 2, mediumFont.width(run) + 2.0f, 15)); + ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB); + ctx->drawText(mediumFont, run, IntPoint(3, y)); + y = 26; + } + + // Draw layer tree, if enabled. + if (m_showPlatformLayerTree) { + ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB); + Vector<String> lines; + m_layerRenderer->layerTreeAsText().split('\n', lines); + for (size_t i = 0; i < lines.size(); ++i) { + ctx->drawText(smallFont, TextRun(lines[i]), IntPoint(2, y)); + y += 12; + } + } +} + +void CCHeadsUpDisplay::onPresent() +{ + m_presentTimeHistoryInSec[m_currentFrameNumber % 2] = currentTime(); + m_currentFrameNumber += 1; +} + +} + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h new file mode 100644 index 0000000..dbac22a --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 CCHeadsUpDisplay_h +#define CCHeadsUpDisplay_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerRendererChromium.h" + +namespace WebCore { + +class GeometryBinding; +class GraphicsContext3D; + +// Class that handles drawing of composited render layers using GL. +class CCHeadsUpDisplay { + WTF_MAKE_NONCOPYABLE(CCHeadsUpDisplay); +public: + static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner) + { + return adoptPtr(new CCHeadsUpDisplay(owner)); + } + + ~CCHeadsUpDisplay(); + + void onPresent(); + + void setShowFPSCounter(bool enable) { m_showFPSCounter = enable; } + bool showFPSCounter() const { return m_showFPSCounter; } + + void setShowPlatformLayerTree(bool enable) { m_showPlatformLayerTree = enable; } + bool showPlatformLayerTree() const { return m_showPlatformLayerTree; } + + bool enabled() const { return true || m_showPlatformLayerTree || m_showFPSCounter; } + void draw(); + +private: + explicit CCHeadsUpDisplay(LayerRendererChromium* owner); + void drawHudContents(GraphicsContext*, const IntSize& hudSize); + + int m_currentFrameNumber; + + OwnPtr<LayerTexture> m_hudTexture; + + LayerRendererChromium* m_layerRenderer; + + double m_presentTimeHistoryInSec[2]; + + bool m_showFPSCounter; + bool m_showPlatformLayerTree; +}; + +} + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp new file mode 100644 index 0000000..a0ad0fb --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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/CCLayerImpl.h" + +#include "GraphicsContext3D.h" +#include "LayerChromium.h" // FIXME: temporary and bad +#include "LayerRendererChromium.h" +#include "RenderSurfaceChromium.h" +#include <wtf/text/WTFString.h> + +namespace { +void toGLMatrix(float* flattened, const WebCore::TransformationMatrix& m) +{ + flattened[0] = m.m11(); + flattened[1] = m.m12(); + flattened[2] = m.m13(); + flattened[3] = m.m14(); + flattened[4] = m.m21(); + flattened[5] = m.m22(); + flattened[6] = m.m23(); + flattened[7] = m.m24(); + flattened[8] = m.m31(); + flattened[9] = m.m32(); + flattened[10] = m.m33(); + flattened[11] = m.m34(); + flattened[12] = m.m41(); + flattened[13] = m.m42(); + flattened[14] = m.m43(); + flattened[15] = m.m44(); +} +} + + +namespace WebCore { + +CCLayerImpl::CCLayerImpl(LayerChromium* owner) + : m_owner(owner) +#ifndef NDEBUG + , m_debugID(owner->debugID()) +#endif + , m_targetRenderSurface(0) + , m_drawDepth(0) + , m_drawOpacity(0) + , m_doubleSided(true) + , m_debugBorderColor(0, 0, 0, 0) + , m_debugBorderWidth(0) + , m_renderSurface(0) + , m_layerRenderer(0) +{ +} + +CCLayerImpl::~CCLayerImpl() +{ +} + +// These are pseudo-structural hacks until we get real tree syncing up in this piece. +CCLayerImpl* CCLayerImpl::superlayer() const +{ + return m_owner->superlayer() ? m_owner->superlayer()->ccLayerImpl() : 0; +} + +CCLayerImpl* CCLayerImpl::maskLayer() const +{ + return m_owner->maskLayer() ? m_owner->maskLayer()->ccLayerImpl() : 0; +} + +CCLayerImpl* CCLayerImpl::replicaLayer() const +{ + return m_owner->replicaLayer() ? m_owner->replicaLayer()->ccLayerImpl() : 0; +} + +void CCLayerImpl::setLayerRenderer(LayerRendererChromium* renderer) +{ + m_layerRenderer = renderer; +} + +RenderSurfaceChromium* CCLayerImpl::createRenderSurface() +{ + m_renderSurface = new RenderSurfaceChromium(this); + return m_renderSurface.get(); +} + +// These belong on CCLayerImpl, but should be subclased by each type and not defer to the LayerChromium subtypes. +bool CCLayerImpl::drawsContent() const +{ + return m_owner->drawsContent(); +} + +void CCLayerImpl::draw() +{ + return m_owner->draw(); +} + +void CCLayerImpl::unreserveContentsTexture() +{ + m_owner->unreserveContentsTexture(); +} + +void CCLayerImpl::bindContentsTexture() +{ + m_owner->bindContentsTexture(); +} + +void CCLayerImpl::cleanupResources() +{ + if (renderSurface()) + renderSurface()->cleanupResources(); +} + +const IntRect CCLayerImpl::getDrawRect() const +{ + // Form the matrix used by the shader to map the corners of the layer's + // bounds into the view space. + FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height()); + IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect)); + return mappedRect; +} + +void CCLayerImpl::drawDebugBorder() +{ + static float glMatrix[16]; + if (!debugBorderColor().alpha()) + return; + + ASSERT(layerRenderer()); + const LayerChromium::BorderProgram* program = layerRenderer()->borderProgram(); + ASSERT(program && program->initialized()); + layerRenderer()->useShader(program->program()); + TransformationMatrix renderMatrix = drawTransform(); + renderMatrix.scale3d(bounds().width(), bounds().height(), 1); + toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); + GraphicsContext3D* context = layerRenderer()->context(); + GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1)); + + GLC(context, context->uniform4f(program->fragmentShader().colorLocation(), debugBorderColor().red() / 255.0, debugBorderColor().green() / 255.0, debugBorderColor().blue() / 255.0, 1)); + + GLC(context, context->lineWidth(debugBorderWidth())); + + // The indices for the line are stored in the same array as the triangle indices. + GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << "bounds: " << bounds().width() << ", " << bounds().height() << "\n"; + + if (m_targetRenderSurface) { + writeIndent(ts, indent); + ts << "targetRenderSurface: " << m_targetRenderSurface->name() << "\n"; + } + + writeIndent(ts, indent); + ts << "drawTransform: "; + ts << m_drawTransform.m11() << ", " << m_drawTransform.m12() << ", " << m_drawTransform.m13() << ", " << m_drawTransform.m14() << ", "; + ts << m_drawTransform.m21() << ", " << m_drawTransform.m22() << ", " << m_drawTransform.m23() << ", " << m_drawTransform.m24() << ", "; + ts << m_drawTransform.m31() << ", " << m_drawTransform.m32() << ", " << m_drawTransform.m33() << ", " << m_drawTransform.m34() << ", "; + ts << m_drawTransform.m41() << ", " << m_drawTransform.m42() << ", " << m_drawTransform.m43() << ", " << m_drawTransform.m44() << "\n"; +} + +} + +#endif // USE(ACCELERATED_COMPOSITING) + diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h new file mode 100644 index 0000000..6892976 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 CCLayerImpl_h +#define CCLayerImpl_h + +#include "Color.h" +#include "FloatRect.h" +#include "IntRect.h" +#include "TextStream.h" +#include "TransformationMatrix.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class LayerChromium; +class LayerRendererChromium; +class RenderSurfaceChromium; + +class CCLayerImpl : public RefCounted<CCLayerImpl> { +public: + static PassRefPtr<CCLayerImpl> create(LayerChromium* owner) + { + return adoptRef(new CCLayerImpl(owner)); + } + // When this class gets subclasses, remember to add 'virtual' here. + ~CCLayerImpl(); + +#ifndef NDEBUG + int debugID() const { return m_debugID; } +#endif + + CCLayerImpl* superlayer() const; + CCLayerImpl* maskLayer() const; + CCLayerImpl* replicaLayer() const; + + void draw(); + bool drawsContent() const; + void unreserveContentsTexture(); + void bindContentsTexture(); + + void cleanupResources(); + + void setName(const String& name) { m_name = name; } + const String& name() const { return m_name; } + + // Debug layer border - visual effect only, do not change geometry/clipping/etc. + void setDebugBorderColor(Color c) { m_debugBorderColor = c; } + Color debugBorderColor() const { return m_debugBorderColor; } + void setDebugBorderWidth(float width) { m_debugBorderWidth = width; } + float debugBorderWidth() const { return m_debugBorderWidth; } + + void drawDebugBorder(); + + void setLayerRenderer(LayerRendererChromium*); + LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); } + + RenderSurfaceChromium* createRenderSurface(); + + RenderSurfaceChromium* renderSurface() const { return m_renderSurface.get(); } + void clearRenderSurface() { m_renderSurface.clear(); } + float drawDepth() const { return m_drawDepth; } + void setDrawDepth(float depth) { m_drawDepth = depth; } + float drawOpacity() const { return m_drawOpacity; } + void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } + const IntRect& scissorRect() const { return m_scissorRect; } + void setScissorRect(const IntRect& rect) { m_scissorRect = rect; } + RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; } + void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; } + + bool doubleSided() const { return m_doubleSided; } + void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; } + const IntSize& bounds() const { return m_bounds; } + void setBounds(const IntSize& bounds) { m_bounds = bounds; } + + // Returns the rect containtaining this layer in the current view's coordinate system. + const IntRect getDrawRect() const; + + const TransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; } + const IntRect& drawableContentRect() const { return m_drawableContentRect; } + void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = rect; } + + virtual void dumpLayerProperties(TextStream&, int indent) const; + +private: + // For now, CCLayers are owned directly by a LayerChromium. + LayerChromium* m_owner; + explicit CCLayerImpl(LayerChromium*); + + // Debugging. +#ifndef NDEBUG + int m_debugID; +#endif + + String m_name; + + // Render surface this layer draws into. This is a surface that can belong + // either to this layer (if m_targetRenderSurface == m_renderSurface) or + // to an ancestor of this layer. The target render surface determines the + // coordinate system the layer's transforms are relative to. + RenderSurfaceChromium* m_targetRenderSurface; + + // The global depth value of the center of the layer. This value is used + // to sort layers from back to front. + float m_drawDepth; + float m_drawOpacity; + + // Whether the "back" of this layer should draw. + bool m_doubleSided; + + // Debug borders. + Color m_debugBorderColor; + float m_debugBorderWidth; + + TransformationMatrix m_drawTransform; + + IntSize m_bounds; + + // The scissor rectangle that should be used when this layer is drawn. + // Inherited by the parent layer and further restricted if this layer masks + // to bounds. + IntRect m_scissorRect; + + // Render surface associated with this layer. The layer and its descendants + // will render to this surface. + OwnPtr<RenderSurfaceChromium> m_renderSurface; + + // Hierarchical bounding rect containing the layer and its descendants. + IntRect m_drawableContentRect; + + // Points to the layer renderer that updates and draws this layer. + RefPtr<LayerRendererChromium> m_layerRenderer; +}; + +} + +#endif // CCLayerImpl_h + diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index ac68266..e5db03e 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -53,9 +53,12 @@ BlendModeType FEBlend::blendMode() const return m_mode; } -void FEBlend::setBlendMode(BlendModeType mode) +bool FEBlend::setBlendMode(BlendModeType mode) { + if (m_mode == mode) + return false; m_mode = mode; + return true; } static unsigned char unknown(unsigned char, unsigned char, unsigned char, unsigned char) diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.h b/Source/WebCore/platform/graphics/filters/FEBlend.h index 4c59578..def33be 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.h +++ b/Source/WebCore/platform/graphics/filters/FEBlend.h @@ -43,7 +43,7 @@ public: static PassRefPtr<FEBlend> create(Filter*, BlendModeType); BlendModeType blendMode() const; - void setBlendMode(BlendModeType); + bool setBlendMode(BlendModeType); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp index 33c4467..f324830 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -52,9 +52,12 @@ ColorMatrixType FEColorMatrix::type() const return m_type; } -void FEColorMatrix::setType(ColorMatrixType type) +bool FEColorMatrix::setType(ColorMatrixType type) { + if (m_type == type) + return false; m_type = type; + return true; } const Vector<float>& FEColorMatrix::values() const @@ -62,9 +65,12 @@ const Vector<float>& FEColorMatrix::values() const return m_values; } -void FEColorMatrix::setValues(const Vector<float> &values) +bool FEColorMatrix::setValues(const Vector<float> &values) { + if (m_values == values) + return false; m_values = values; + return true; } inline void matrix(double& red, double& green, double& blue, double& alpha, const Vector<float>& values) diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h index a3ced7e..5bdfa74 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h @@ -43,10 +43,10 @@ public: static PassRefPtr<FEColorMatrix> create(Filter*, ColorMatrixType, const Vector<float>&); ColorMatrixType type() const; - void setType(ColorMatrixType); + bool setType(ColorMatrixType); const Vector<float>& values() const; - void setValues(const Vector<float>&); + bool setValues(const Vector<float>&); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp index bc7fa80..eead000 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp @@ -55,9 +55,12 @@ CompositeOperationType FEComposite::operation() const return m_type; } -void FEComposite::setOperation(CompositeOperationType type) +bool FEComposite::setOperation(CompositeOperationType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FEComposite::k1() const @@ -65,9 +68,12 @@ float FEComposite::k1() const return m_k1; } -void FEComposite::setK1(float k1) +bool FEComposite::setK1(float k1) { + if (m_k1 == k1) + return false; m_k1 = k1; + return true; } float FEComposite::k2() const @@ -75,9 +81,12 @@ float FEComposite::k2() const return m_k2; } -void FEComposite::setK2(float k2) +bool FEComposite::setK2(float k2) { + if (m_k2 == k2) + return false; m_k2 = k2; + return true; } float FEComposite::k3() const @@ -85,9 +94,12 @@ float FEComposite::k3() const return m_k3; } -void FEComposite::setK3(float k3) +bool FEComposite::setK3(float k3) { + if (m_k3 == k3) + return false; m_k3 = k3; + return true; } float FEComposite::k4() const @@ -95,9 +107,12 @@ float FEComposite::k4() const return m_k4; } -void FEComposite::setK4(float k4) +bool FEComposite::setK4(float k4) { + if (m_k4 == k4) + return false; m_k4 = k4; + return true; } template <int b1, int b2, int b3, int b4> diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.h b/Source/WebCore/platform/graphics/filters/FEComposite.h index b846902..481c6a7 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.h +++ b/Source/WebCore/platform/graphics/filters/FEComposite.h @@ -45,19 +45,19 @@ public: static PassRefPtr<FEComposite> create(Filter*, const CompositeOperationType&, float, float, float, float); CompositeOperationType operation() const; - void setOperation(CompositeOperationType); + bool setOperation(CompositeOperationType); float k1() const; - void setK1(float); + bool setK1(float); float k2() const; - void setK2(float); + bool setK2(float); float k3() const; - void setK3(float); + bool setK3(float); float k4() const; - void setK4(float); + bool setK4(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp index 0483626..a1f8dfd 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp @@ -63,7 +63,7 @@ IntSize FEConvolveMatrix::kernelSize() const return m_kernelSize; } -void FEConvolveMatrix::setKernelSize(IntSize kernelSize) +void FEConvolveMatrix::setKernelSize(const IntSize& kernelSize) { m_kernelSize = kernelSize; } @@ -83,9 +83,12 @@ float FEConvolveMatrix::divisor() const return m_divisor; } -void FEConvolveMatrix::setDivisor(float divisor) +bool FEConvolveMatrix::setDivisor(float divisor) { - m_divisor = divisor; + if (m_divisor == divisor) + return false; + m_divisor = divisor; + return true; } float FEConvolveMatrix::bias() const @@ -93,9 +96,12 @@ float FEConvolveMatrix::bias() const return m_bias; } -void FEConvolveMatrix::setBias(float bias) +bool FEConvolveMatrix::setBias(float bias) { - m_bias = bias; + if (m_bias == bias) + return false; + m_bias = bias; + return true; } IntPoint FEConvolveMatrix::targetOffset() const @@ -103,19 +109,25 @@ IntPoint FEConvolveMatrix::targetOffset() const return m_targetOffset; } -void FEConvolveMatrix::setTargetOffset(IntPoint targetOffset) +bool FEConvolveMatrix::setTargetOffset(const IntPoint& targetOffset) { - m_targetOffset = targetOffset; + if (m_targetOffset == targetOffset) + return false; + m_targetOffset = targetOffset; + return true; } EdgeModeType FEConvolveMatrix::edgeMode() const { - return m_edgeMode; + return m_edgeMode; } -void FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode) +bool FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode) { - m_edgeMode = edgeMode; + if (m_edgeMode == edgeMode) + return false; + m_edgeMode = edgeMode; + return true; } FloatPoint FEConvolveMatrix::kernelUnitLength() const @@ -123,9 +135,12 @@ FloatPoint FEConvolveMatrix::kernelUnitLength() const return m_kernelUnitLength; } -void FEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength) +bool FEConvolveMatrix::setKernelUnitLength(const FloatPoint& kernelUnitLength) { - m_kernelUnitLength = kernelUnitLength; + if (m_kernelUnitLength == kernelUnitLength) + return false; + m_kernelUnitLength = kernelUnitLength; + return true; } bool FEConvolveMatrix::preserveAlpha() const @@ -133,9 +148,12 @@ bool FEConvolveMatrix::preserveAlpha() const return m_preserveAlpha; } -void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) +bool FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) { - m_preserveAlpha = preserveAlpha; + if (m_preserveAlpha == preserveAlpha) + return false; + m_preserveAlpha = preserveAlpha; + return true; } /* diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h index 05d1199..5dc8873 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h @@ -49,28 +49,28 @@ public: bool, const Vector<float>&); IntSize kernelSize() const; - void setKernelSize(IntSize); + void setKernelSize(const IntSize&); const Vector<float>& kernel() const; void setKernel(const Vector<float>&); float divisor() const; - void setDivisor(float); + bool setDivisor(float); float bias() const; - void setBias(float); + bool setBias(float); IntPoint targetOffset() const; - void setTargetOffset(IntPoint); + bool setTargetOffset(const IntPoint&); EdgeModeType edgeMode() const; - void setEdgeMode(EdgeModeType); + bool setEdgeMode(EdgeModeType); FloatPoint kernelUnitLength() const; - void setKernelUnitLength(FloatPoint); + bool setKernelUnitLength(const FloatPoint&); bool preserveAlpha() const; - void setPreserveAlpha(bool); + bool setPreserveAlpha(bool); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index 88c87b7..b632233 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -54,9 +54,12 @@ ChannelSelectorType FEDisplacementMap::xChannelSelector() const return m_xChannelSelector; } -void FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector) +bool FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector) { + if (m_xChannelSelector == xChannelSelector) + return false; m_xChannelSelector = xChannelSelector; + return true; } ChannelSelectorType FEDisplacementMap::yChannelSelector() const @@ -64,9 +67,12 @@ ChannelSelectorType FEDisplacementMap::yChannelSelector() const return m_yChannelSelector; } -void FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector) +bool FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector) { + if (m_yChannelSelector == yChannelSelector) + return false; m_yChannelSelector = yChannelSelector; + return true; } float FEDisplacementMap::scale() const @@ -74,9 +80,12 @@ float FEDisplacementMap::scale() const return m_scale; } -void FEDisplacementMap::setScale(float scale) +bool FEDisplacementMap::setScale(float scale) { + if (m_scale == scale) + return false; m_scale = scale; + return true; } void FEDisplacementMap::apply() diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h index ffb8f0e..9b7dda8 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h @@ -42,13 +42,13 @@ public: static PassRefPtr<FEDisplacementMap> create(Filter*, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float); ChannelSelectorType xChannelSelector() const; - void setXChannelSelector(const ChannelSelectorType); + bool setXChannelSelector(const ChannelSelectorType); ChannelSelectorType yChannelSelector() const; - void setYChannelSelector(const ChannelSelectorType); + bool setYChannelSelector(const ChannelSelectorType); float scale() const; - void setScale(float scale); + bool setScale(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp index 0e0e94c..3c48cf9 100644 --- a/Source/WebCore/platform/graphics/filters/FEFlood.cpp +++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp @@ -85,7 +85,7 @@ TextStream& FEFlood::externalRepresentation(TextStream& ts, int indent) const writeIndent(ts, indent); ts << "[feFlood"; FilterEffect::externalRepresentation(ts); - ts << " flood-color=\"" << floodColor().name() << "\" " + ts << " flood-color=\"" << floodColor().nameForRenderTreeAsText() << "\" " << "flood-opacity=\"" << floodOpacity() << "\"]\n"; return ts; } diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp index 1eb554b..aa01570 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -56,9 +56,12 @@ MorphologyOperatorType FEMorphology::morphologyOperator() const return m_type; } -void FEMorphology::setMorphologyOperator(MorphologyOperatorType type) +bool FEMorphology::setMorphologyOperator(MorphologyOperatorType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FEMorphology::radiusX() const @@ -66,9 +69,12 @@ float FEMorphology::radiusX() const return m_radiusX; } -void FEMorphology::setRadiusX(float radiusX) +bool FEMorphology::setRadiusX(float radiusX) { + if (m_radiusX == radiusX) + return false; m_radiusX = radiusX; + return true; } float FEMorphology::radiusY() const @@ -86,9 +92,12 @@ void FEMorphology::determineAbsolutePaintRect() setAbsolutePaintRect(enclosingIntRect(paintRect)); } -void FEMorphology::setRadiusY(float radiusY) +bool FEMorphology::setRadiusY(float radiusY) { + if (m_radiusY == radiusY) + return false; m_radiusY = radiusY; + return true; } void FEMorphology::apply() diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.h b/Source/WebCore/platform/graphics/filters/FEMorphology.h index 683e7d0..74c3b5a 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.h +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.h @@ -38,13 +38,13 @@ class FEMorphology : public FilterEffect { public: static PassRefPtr<FEMorphology> create(Filter*, MorphologyOperatorType, float radiusX, float radiusY); MorphologyOperatorType morphologyOperator() const; - void setMorphologyOperator(MorphologyOperatorType); + bool setMorphologyOperator(MorphologyOperatorType); float radiusX() const; - void setRadiusX(float); + bool setRadiusX(float); float radiusY() const; - void setRadiusY(float); + bool setRadiusY(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp index 36a6b72..a20eb8c 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp @@ -64,9 +64,12 @@ float FESpecularLighting::surfaceScale() const return m_surfaceScale; } -void FESpecularLighting::setSurfaceScale(float surfaceScale) +bool FESpecularLighting::setSurfaceScale(float surfaceScale) { + if (m_surfaceScale == surfaceScale) + return false; m_surfaceScale = surfaceScale; + return true; } float FESpecularLighting::specularConstant() const @@ -74,9 +77,12 @@ float FESpecularLighting::specularConstant() const return m_specularConstant; } -void FESpecularLighting::setSpecularConstant(float specularConstant) +bool FESpecularLighting::setSpecularConstant(float specularConstant) { + if (m_specularConstant == specularConstant) + return false; m_specularConstant = specularConstant; + return true; } float FESpecularLighting::specularExponent() const @@ -84,9 +90,12 @@ float FESpecularLighting::specularExponent() const return m_specularExponent; } -void FESpecularLighting::setSpecularExponent(float specularExponent) +bool FESpecularLighting::setSpecularExponent(float specularExponent) { + if (m_specularExponent == specularExponent) + return false; m_specularExponent = specularExponent; + return true; } float FESpecularLighting::kernelUnitLengthX() const @@ -94,9 +103,12 @@ float FESpecularLighting::kernelUnitLengthX() const return m_kernelUnitLengthX; } -void FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) +bool FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) { + if (m_kernelUnitLengthX == kernelUnitLengthX) + return false; m_kernelUnitLengthX = kernelUnitLengthX; + return true; } float FESpecularLighting::kernelUnitLengthY() const @@ -104,9 +116,12 @@ float FESpecularLighting::kernelUnitLengthY() const return m_kernelUnitLengthY; } -void FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) +bool FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) { + if (m_kernelUnitLengthY == kernelUnitLengthY) + return false; m_kernelUnitLengthY = kernelUnitLengthY; + return true; } const LightSource* FESpecularLighting::lightSource() const diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h index b3ccfbc..9d3ea2d 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h @@ -37,19 +37,19 @@ public: void setLightingColor(const Color&); float surfaceScale() const; - void setSurfaceScale(float); + bool setSurfaceScale(float); float specularConstant() const; - void setSpecularConstant(float); + bool setSpecularConstant(float); float specularExponent() const; - void setSpecularExponent(float); + bool setSpecularExponent(float); float kernelUnitLengthX() const; - void setKernelUnitLengthX(float); + bool setKernelUnitLengthX(float); float kernelUnitLengthY() const; - void setKernelUnitLengthY(float); + bool setKernelUnitLengthY(float); const LightSource* lightSource() const; void setLightSource(PassRefPtr<LightSource>); diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp index 068acee..63060e1 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -49,7 +49,7 @@ static const int s_randAmplitude = 16807; // 7**5; primitive root of m static const int s_randQ = 127773; // m / a static const int s_randR = 2836; // m % a -FETurbulence::FETurbulence(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) +FETurbulence::FETurbulence(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) : FilterEffect(filter) , m_type(type) , m_baseFrequencyX(baseFrequencyX) @@ -60,19 +60,22 @@ FETurbulence::FETurbulence(Filter* filter, TurbulanceType type, float baseFreque { } -PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) +PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) { return adoptRef(new FETurbulence(filter, type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles)); } -TurbulanceType FETurbulence::type() const +TurbulenceType FETurbulence::type() const { return m_type; } -void FETurbulence::setType(TurbulanceType type) +bool FETurbulence::setType(TurbulenceType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FETurbulence::baseFrequencyY() const @@ -80,9 +83,12 @@ float FETurbulence::baseFrequencyY() const return m_baseFrequencyY; } -void FETurbulence::setBaseFrequencyY(float baseFrequencyY) +bool FETurbulence::setBaseFrequencyY(float baseFrequencyY) { + if (m_baseFrequencyY == baseFrequencyY) + return false; m_baseFrequencyY = baseFrequencyY; + return true; } float FETurbulence::baseFrequencyX() const @@ -90,9 +96,12 @@ float FETurbulence::baseFrequencyX() const return m_baseFrequencyX; } -void FETurbulence::setBaseFrequencyX(float baseFrequencyX) +bool FETurbulence::setBaseFrequencyX(float baseFrequencyX) { - m_baseFrequencyX = baseFrequencyX; + if (m_baseFrequencyX == baseFrequencyX) + return false; + m_baseFrequencyX = baseFrequencyX; + return true; } float FETurbulence::seed() const @@ -100,9 +109,12 @@ float FETurbulence::seed() const return m_seed; } -void FETurbulence::setSeed(float seed) +bool FETurbulence::setSeed(float seed) { + if (m_seed == seed) + return false; m_seed = seed; + return true; } int FETurbulence::numOctaves() const @@ -110,9 +122,12 @@ int FETurbulence::numOctaves() const return m_numOctaves; } -void FETurbulence::setNumOctaves(bool numOctaves) +bool FETurbulence::setNumOctaves(int numOctaves) { + if (m_numOctaves == numOctaves) + return false; m_numOctaves = numOctaves; + return true; } bool FETurbulence::stitchTiles() const @@ -120,9 +135,12 @@ bool FETurbulence::stitchTiles() const return m_stitchTiles; } -void FETurbulence::setStitchTiles(bool stitch) +bool FETurbulence::setStitchTiles(bool stitch) { + if (m_stitchTiles == stitch) + return false; m_stitchTiles = stitch; + return true; } // The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification: @@ -353,7 +371,7 @@ void FETurbulence::dump() { } -static TextStream& operator<<(TextStream& ts, const TurbulanceType& type) +static TextStream& operator<<(TextStream& ts, const TurbulenceType& type) { switch (type) { case FETURBULENCE_TYPE_UNKNOWN: diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.h b/Source/WebCore/platform/graphics/filters/FETurbulence.h index 1bad123..dfeb220 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.h +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.h @@ -30,7 +30,7 @@ namespace WebCore { -enum TurbulanceType { +enum TurbulenceType { FETURBULENCE_TYPE_UNKNOWN = 0, FETURBULENCE_TYPE_FRACTALNOISE = 1, FETURBULENCE_TYPE_TURBULENCE = 2 @@ -38,25 +38,25 @@ enum TurbulanceType { class FETurbulence : public FilterEffect { public: - static PassRefPtr<FETurbulence> create(Filter*, TurbulanceType, float, float, int, float, bool); + static PassRefPtr<FETurbulence> create(Filter*, TurbulenceType, float, float, int, float, bool); - TurbulanceType type() const; - void setType(TurbulanceType); + TurbulenceType type() const; + bool setType(TurbulenceType); float baseFrequencyY() const; - void setBaseFrequencyY(float); + bool setBaseFrequencyY(float); float baseFrequencyX() const; - void setBaseFrequencyX(float); + bool setBaseFrequencyX(float); float seed() const; - void setSeed(float); + bool setSeed(float); int numOctaves() const; - void setNumOctaves(bool); + bool setNumOctaves(int); bool stitchTiles() const; - void setStitchTiles(bool); + bool setStitchTiles(bool); virtual void apply(); virtual void dump(); @@ -84,13 +84,13 @@ private: inline long random(); }; - FETurbulence(Filter*, TurbulanceType, float, float, int, float, bool); + FETurbulence(Filter*, TurbulenceType, float, float, int, float, bool); inline void initPaint(PaintingData&); float noise2D(PaintingData&, const FloatPoint&); unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&); - TurbulanceType m_type; + TurbulenceType m_type; float m_baseFrequencyX; float m_baseFrequencyY; int m_numOctaves; diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp index 1430124..b27bead 100644 --- a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp @@ -142,6 +142,33 @@ static String getFamilyNameStringFromFontDescriptionAndFamily(const FontDescript } } +int fontWeightToFontconfigWeight(FontWeight weight) +{ + switch (weight) { + case FontWeight100: + return FC_WEIGHT_THIN; + case FontWeight200: + return FC_WEIGHT_ULTRALIGHT; + case FontWeight300: + return FC_WEIGHT_LIGHT; + case FontWeight400: + return FC_WEIGHT_REGULAR; + case FontWeight500: + return FC_WEIGHT_MEDIUM; + case FontWeight600: + return FC_WEIGHT_SEMIBOLD; + case FontWeight700: + return FC_WEIGHT_BOLD; + case FontWeight800: + return FC_WEIGHT_EXTRABOLD; + case FontWeight900: + return FC_WEIGHT_ULTRABLACK; + default: + ASSERT_NOT_REACHED(); + return FC_WEIGHT_REGULAR; + } +} + FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm) @@ -155,8 +182,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD bool italic = fontDescription.italic(); if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN)) return 0; - bool bold = fontDescription.weight() >= FontWeightBold; - if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL)) + if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight()))) return 0; if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize())) return 0; diff --git a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp index 7340e76..fbc7ac9 100644 --- a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp @@ -31,7 +31,7 @@ #include <cairo.h> #include <fontconfig/fcfreetype.h> -#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) +#if !PLATFORM(EFL) #include <gdk/gdk.h> #endif @@ -100,17 +100,16 @@ void setCairoFontOptionsFromFontConfigPattern(cairo_font_options_t* options, FcP cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE); } -static const cairo_font_options_t* getDefaultFontOptions() +static cairo_font_options_t* getDefaultFontOptions() { - static const cairo_font_options_t* options = cairo_font_options_create(); -#if PLATFORM(GTK) || ENABLE(GLIB_SUPPORT) +#if PLATFORM(GTK) if (GdkScreen* screen = gdk_screen_get_default()) { const cairo_font_options_t* screenOptions = gdk_screen_get_font_options(screen); if (screenOptions) - options = screenOptions; + return cairo_font_options_copy(screenOptions); } #endif - return options; + return cairo_font_options_create(); } FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription) @@ -242,7 +241,7 @@ String FontPlatformData::description() const void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace) { - cairo_font_options_t* options = cairo_font_options_copy(getDefaultFontOptions()); + cairo_font_options_t* options = getDefaultFontOptions(); cairo_matrix_t ctm; cairo_matrix_init_identity(&ctm); diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h index 1bd67b8..8b7181b 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h @@ -30,6 +30,7 @@ #ifndef LoopBlinnClassifier_h #define LoopBlinnClassifier_h +#include <wtf/Noncopyable.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h index d01e6c9..aa2294e 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h @@ -30,6 +30,7 @@ #include "FloatPoint3D.h" #include "LoopBlinnConstants.h" #include <wtf/Assertions.h> +#include <wtf/Noncopyable.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp index e84ddbf..5439885 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp @@ -43,7 +43,7 @@ #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> -#if PLATFORM(SKIA) +#if USE(SKIA) #include "SkGeometry.h" #include "SkPath.h" #include "SkScalar.h" @@ -612,7 +612,7 @@ void LoopBlinnPathProcessor::buildContours(const Path& path) { // Clear out the contours m_contours.clear(); -#if PLATFORM(SKIA) +#if USE(SKIA) SkPath::Iter iter(*path.platformPath(), false); SkPoint points[4]; SkPath::Verb verb; @@ -700,7 +700,7 @@ void LoopBlinnPathProcessor::buildContours(const Path& path) break; } } while (verb != SkPath::kDone_Verb); -#else // !PLATFORM(SKIA) +#else // !USE(SKIA) // Must port to your platform. ASSERT_NOT_REACHED(); #endif diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp index 43a97ef..57b728f 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp @@ -27,6 +27,7 @@ #include "LoopBlinnSolidFillShader.h" +#include "Color.h" #include "GraphicsContext3D.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp index 9c59077..ea8bc71 100644 --- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp +++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp @@ -39,6 +39,7 @@ #include "Extensions3D.h" #include "FloatRect.h" #include "IntSize.h" +#include "LoopBlinnSolidFillShader.h" #include "SolidFillShader.h" #include "TexShader.h" @@ -53,7 +54,7 @@ PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* GraphicsContext3D::Attributes attr; attr.depth = false; attr.stencil = true; - attr.antialias = false; + attr.antialias = useLoopBlinnForPathRendering(); attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts. RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow); if (!context) @@ -73,6 +74,7 @@ SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> c , m_quadVertices(0) , m_solidFillShader(solidFillShader) , m_texShader(texShader) + , m_oesStandardDerivativesSupported(false) { allContexts()->add(this); Extensions3D* extensions = m_context->getExtensions(); @@ -81,6 +83,9 @@ SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> c extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888"); extensions->ensureEnabled("GL_EXT_read_format_bgra"); } + m_oesStandardDerivativesSupported = extensions->supports("GL_OES_standard_derivatives"); + if (m_oesStandardDerivativesSupported) + extensions->ensureEnabled("GL_OES_standard_derivatives"); } SharedGraphicsContext3D::~SharedGraphicsContext3D() @@ -94,9 +99,9 @@ void SharedGraphicsContext3D::makeContextCurrent() m_context->makeContextCurrent(); } -void SharedGraphicsContext3D::scissor(const FloatRect& rect) +void SharedGraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) { - m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height()); + m_context->scissor(x, y, width, height); } void SharedGraphicsContext3D::enable(GC3Denum capacity) @@ -141,6 +146,11 @@ void SharedGraphicsContext3D::flush() m_context->flush(); } +Platform3DObject SharedGraphicsContext3D::createBuffer() +{ + return m_context->createBuffer(); +} + Platform3DObject SharedGraphicsContext3D::createFramebuffer() { return m_context->createFramebuffer(); @@ -324,11 +334,31 @@ void SharedGraphicsContext3D::setActiveTexture(GC3Denum textureUnit) m_context->activeTexture(textureUnit); } +void SharedGraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer) +{ + m_context->bindBuffer(target, buffer); +} + void SharedGraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture) { m_context->bindTexture(target, texture); } +void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage) +{ + m_context->bufferData(target, size, usage); +} + +void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage) +{ + m_context->bufferData(target, size, data, usage); +} + +void SharedGraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data) +{ + m_context->bufferSubData(target, offset, size, data); +} + void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color) { m_solidFillShader->use(transform, color); @@ -354,6 +384,33 @@ bool SharedGraphicsContext3D::paintsIntoCanvasBuffer() const return m_context->paintsIntoCanvasBuffer(); } +bool SharedGraphicsContext3D::useLoopBlinnForPathRendering() +{ + return false; +} + +void SharedGraphicsContext3D::useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform& transform, const Color& color) +{ + if (!m_loopBlinnInteriorShader) { + m_loopBlinnInteriorShader = LoopBlinnSolidFillShader::create(m_context.get(), + LoopBlinnShader::Interior, + Shader::NotAntialiased); + } + ASSERT(m_loopBlinnInteriorShader); + m_loopBlinnInteriorShader->use(vertexOffset, 0, transform, color); +} + +void SharedGraphicsContext3D::useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform, const Color& color) +{ + if (!m_loopBlinnExteriorShader) { + m_loopBlinnExteriorShader = LoopBlinnSolidFillShader::create(m_context.get(), + LoopBlinnShader::Exterior, + m_oesStandardDerivativesSupported ? Shader::Antialiased : Shader::NotAntialiased); + } + ASSERT(m_loopBlinnExteriorShader); + m_loopBlinnExteriorShader->use(vertexOffset, klmOffset, transform, color); +} + } // namespace WebCore #endif diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h index 1e032d7..707fd24 100644 --- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h @@ -49,6 +49,7 @@ class Color; class FloatRect; class HostWindow; class IntSize; +class LoopBlinnSolidFillShader; class SolidFillShader; class TexShader; @@ -61,9 +62,13 @@ public: // Functions that delegate directly to GraphicsContext3D, with caching void makeContextCurrent(); + void bindBuffer(GC3Denum target, Platform3DObject); void bindFramebuffer(Platform3DObject framebuffer); + void bufferData(GC3Denum target, GC3Dsizeiptr, GC3Denum usage); + void bufferData(GC3Denum target, GC3Dsizeiptr, const void* data, GC3Denum usage); + void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr, const void* data); void setViewport(const IntSize&); - void scissor(const FloatRect&); + void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); void enable(GC3Denum capacity); void disable(GC3Denum capacity); void clearColor(const Color&); @@ -73,6 +78,7 @@ public: void getIntegerv(GC3Denum pname, GC3Dint* value); void flush(); + Platform3DObject createBuffer(); Platform3DObject createFramebuffer(); Platform3DObject createTexture(); @@ -117,6 +123,11 @@ public: GraphicsContext3D* graphicsContext3D() const { return m_context.get(); } + // Members for GPU-accelerated path rendering. + static bool useLoopBlinnForPathRendering(); + void useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform&, const Color&); + void useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&, const Color&); + private: SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D>, PassOwnPtr<SolidFillShader>, PassOwnPtr<TexShader>); @@ -133,6 +144,12 @@ private: OwnPtr<TexShader> m_texShader; TextureHashMap m_textures; + + // Members for GPU-accelerated path rendering. + // FIXME: support more kinds of fill types for paths. + OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnInteriorShader; + OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnExteriorShader; + bool m_oesStandardDerivativesSupported; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.cpp b/Source/WebCore/platform/graphics/gpu/TilingData.cpp index e7c4e4c..dd540b3 100644 --- a/Source/WebCore/platform/graphics/gpu/TilingData.cpp +++ b/Source/WebCore/platform/graphics/gpu/TilingData.cpp @@ -44,7 +44,8 @@ namespace WebCore { static int computeNumTiles(int maxTextureSize, int totalSize, int borderTexels) { - return max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); + int numTiles = max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); + return totalSize > 0 ? numTiles : 0; } TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels) @@ -53,8 +54,20 @@ TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool , m_totalSizeY(totalSizeY) , m_borderTexels(hasBorderTexels ? 1 : 0) { - m_numTilesX = computeNumTiles(maxTextureSize, m_totalSizeX, m_borderTexels); - m_numTilesY = computeNumTiles(maxTextureSize, m_totalSizeY, m_borderTexels); + recomputeNumTiles(); +} + +void TilingData::setTotalSize(int totalSizeX, int totalSizeY) +{ + m_totalSizeX = totalSizeX; + m_totalSizeY = totalSizeY; + recomputeNumTiles(); +} + +void TilingData::setMaxTextureSize(int maxTextureSize) +{ + m_maxTextureSize = m_maxTextureSize; + recomputeNumTiles(); } int TilingData::tileXIndexFromSrcCoord(int srcPos) const @@ -142,9 +155,6 @@ int TilingData::tileSizeX(int xIndex) const { ASSERT(xIndex >= 0 && xIndex < numTilesX()); - int size = maxTextureSize(); - size = min(size, totalSizeX()); - if (!xIndex && m_numTilesX == 1) return m_totalSizeX; if (!xIndex && m_numTilesX > 1) @@ -162,9 +172,6 @@ int TilingData::tileSizeY(int yIndex) const { ASSERT(yIndex >= 0 && yIndex < numTilesY()); - int size = maxTextureSize(); - size = min(size, totalSizeY()); - if (!yIndex && m_numTilesY == 1) return m_totalSizeY; if (!yIndex && m_numTilesY > 1) @@ -222,6 +229,20 @@ void TilingData::intersectDrawQuad(const FloatRect& srcRect, const FloatRect& ds srcRectIntersectedNormH * dstRect.height()); } +IntPoint TilingData::textureOffset(int xIndex, int yIndex) const +{ + int left = (!xIndex || m_numTilesX == 1) ? 0 : m_borderTexels; + int top = (!yIndex || m_numTilesY == 1) ? 0 : m_borderTexels; + + return IntPoint(left, top); +} + +void TilingData::recomputeNumTiles() +{ + m_numTilesX = computeNumTiles(m_maxTextureSize, m_totalSizeX, m_borderTexels); + m_numTilesY = computeNumTiles(m_maxTextureSize, m_totalSizeY, m_borderTexels); +} + } #endif diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.h b/Source/WebCore/platform/graphics/gpu/TilingData.h index d1140bd..2989eae 100644 --- a/Source/WebCore/platform/graphics/gpu/TilingData.h +++ b/Source/WebCore/platform/graphics/gpu/TilingData.h @@ -37,11 +37,14 @@ namespace WebCore { class FloatRect; class IntRect; +class IntPoint; class TilingData { WTF_MAKE_NONCOPYABLE(TilingData); public: TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels); + void setTotalSize(int totalSizeX, int totalSizeY); + void setMaxTextureSize(int); int maxTextureSize() const { return m_maxTextureSize; } int totalSizeX() const { return m_totalSizeX; } int totalSizeY() const { return m_totalSizeY; } @@ -70,9 +73,13 @@ public: // in texel units, returns adjusted data to render just the one tile. void intersectDrawQuad(const FloatRect& srcRect, const FloatRect& dstRect, int tile, FloatRect* newSrc, FloatRect* newDst) const; + // Difference between tileBound's and tileBoundWithBorder's location(). + IntPoint textureOffset(int xIndex, int yIndex) const; + private: TilingData() : m_maxTextureSize(0), m_totalSizeX(0), m_totalSizeY(0) {} void assertTile(int tile) const { ASSERT(tile >= 0 && tile < numTiles()); } + void recomputeNumTiles(); int m_maxTextureSize; int m_totalSizeX; diff --git a/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp b/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp new file mode 100644 index 0000000..b8c3b3d --- /dev/null +++ b/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 Andrew Wason (rectalogic@rectalogic.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(WEBGL) + +#include "DrawingBuffer.h" + +namespace WebCore { + +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) + : m_context(context) + , m_size(-1, -1) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) + , m_fbo(context->createFramebuffer()) + , m_colorBuffer(0) + , m_depthStencilBuffer(0) + , m_depthBuffer(0) + , m_stencilBuffer(0) + , m_multisampleFBO(0) + , m_multisampleColorBuffer(0) +{ + ASSERT(m_fbo); + if (!m_fbo) { + clear(); + return; + } + + // create a texture to render into + m_colorBuffer = context->createTexture(); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer); + context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); + context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); + + // Create the FBO + m_fbo = context->createFramebuffer(); + ASSERT(m_fbo); + if (!m_fbo) { + clear(); + return; + } + + createSecondaryBuffers(); + reset(size); +} + +DrawingBuffer::~DrawingBuffer() +{ + clear(); +} + +void DrawingBuffer::didReset() +{ +} + +#if USE(ACCELERATED_COMPOSITING) +PlatformLayer* DrawingBuffer::platformLayer() +{ + return 0; +} +#endif + +Platform3DObject DrawingBuffer::platformColorBuffer() const +{ + return m_colorBuffer; +} + +} + +#endif diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp new file mode 100644 index 0000000..91b65d8 --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "config.h" +#include "GRefPtrGStreamer.h" + +#if USE(GSTREAMER) +#include <gst/gstelement.h> + +namespace WTF { + +template <> GstElement* refGPtr<GstElement>(GstElement* ptr) +{ + if (ptr) + gst_object_ref(ptr); + return ptr; +} + +template <> void derefGPtr<GstElement>(GstElement* ptr) +{ + if (ptr) + gst_object_unref(ptr); +} + +} +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/graphics/wince/ColorWinCE.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h index 820b9d2..fdc6f30 100644 --- a/Source/WebCore/platform/graphics/wince/ColorWinCE.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Torch Mobile, Inc. + * Copyright (C) 2011 Igalia S.L * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -15,24 +15,22 @@ * 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 "Color.h" +#ifndef GRefPtrGStreamer_h +#define GRefPtrGStreamer_h +#if USE(GSTREAMER) -#include "NotImplemented.h" +#include "GRefPtr.h" -namespace WebCore { +typedef struct _GstElement GstElement; -Color focusRingColor() -{ - return Color(0, 0, 0); -} +namespace WTF { + +template<> GstElement* refGPtr<GstElement>(GstElement* ptr); +template<> void derefGPtr<GstElement>(GstElement* ptr); -void setFocusRingColorChangeFunction(void (*)()) -{ - notImplemented(); } -} // namespace WebCore +#endif // USE(GSTREAMER) +#endif diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 69bdeab..3763ef7 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -46,6 +46,7 @@ #include "WebKitWebSourceGStreamer.h" #include <GOwnPtr.h> #include <gst/gst.h> +#include <gst/interfaces/streamvolume.h> #include <gst/video/video.h> #include <limits> #include <math.h> @@ -271,7 +272,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateGStreamer::create(MediaPlayer* pl void MediaPlayerPrivateGStreamer::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } static bool gstInitialized = false; @@ -640,7 +641,8 @@ void MediaPlayerPrivateGStreamer::setVolume(float volume) if (!m_playBin) return; - g_object_set(m_playBin, "volume", static_cast<double>(volume), NULL); + gst_stream_volume_set_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC, + static_cast<double>(volume)); } void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange() @@ -650,7 +652,11 @@ void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange() if (!m_player || !m_playBin) return; double volume; - g_object_get(m_playBin, "volume", &volume, NULL); + volume = gst_stream_volume_get_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC); + // get_volume() can return values superior to 1.0 if the user + // applies software user gain via third party application (GNOME + // volume control for instance). + volume = CLAMP(volume, 0.0, 1.0); m_player->volumeChanged(static_cast<float>(volume)); } @@ -1561,7 +1567,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin() g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this); gst_object_unref(bus); - g_object_set(m_playBin, "mute", m_player->muted(), "volume", m_player->volume(), NULL); + g_object_set(m_playBin, "mute", m_player->muted(), NULL); g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this); g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this); diff --git a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp index 36b49df..86e3e7a 100644 --- a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp @@ -23,6 +23,7 @@ #include "Document.h" #include "GOwnPtr.h" #include "GRefPtr.h" +#include "GRefPtrGStreamer.h" #include "NetworkingContext.h" #include "Noncopyable.h" #include "NotImplemented.h" @@ -93,7 +94,8 @@ enum { PROP_IRADIO_NAME, PROP_IRADIO_GENRE, PROP_IRADIO_URL, - PROP_IRADIO_TITLE + PROP_IRADIO_TITLE, + PROP_LOCATION }; static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE("src", @@ -118,6 +120,8 @@ static void webKitWebSrcEnoughDataCb(GstAppSrc* appsrc, gpointer userData); static gboolean webKitWebSrcSeekDataCb(GstAppSrc* appsrc, guint64 offset, gpointer userData); static void webKitWebSrcStop(WebKitWebSrc* src, bool seeking); +static gboolean webKitWebSrcSetUri(GstURIHandler*, const gchar*); +static const gchar* webKitWebSrcGetUri(GstURIHandler*); static GstAppSrcCallbacks appsrcCallbacks = { webKitWebSrcNeedDataCb, @@ -203,6 +207,16 @@ static void webkit_web_src_class_init(WebKitWebSrcClass* klass) 0, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); + + /* Allows setting the uri using the 'location' property, which is used + * for example by gst_element_make_from_uri() */ + g_object_class_install_property(oklass, + PROP_LOCATION, + g_param_spec_string("location", + "location", + "Location to read from", + 0, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); eklass->change_state = webKitWebSrcChangeState; g_type_class_add_private(klass, sizeof(WebKitWebSrcPrivate)); @@ -288,6 +302,9 @@ static void webKitWebSrcSetProperty(GObject* object, guint propID, const GValue* case PROP_IRADIO_MODE: priv->iradioMode = g_value_get_boolean(value); break; + case PROP_LOCATION: + webKitWebSrcSetUri(reinterpret_cast<GstURIHandler*>(src), g_value_get_string(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec); break; @@ -315,6 +332,9 @@ static void webKitWebSrcGetProperty(GObject* object, guint propID, GValue* value case PROP_IRADIO_TITLE: g_value_set_string(value, priv->iradioTitle); break; + case PROP_LOCATION: + g_value_set_string(value, webKitWebSrcGetUri(reinterpret_cast<GstURIHandler*>(src))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec); break; @@ -481,7 +501,8 @@ static GstStateChangeReturn webKitWebSrcChangeState(GstElement* element, GstStat static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) { - WebKitWebSrc* src = WEBKIT_WEB_SRC(gst_pad_get_parent(pad)); + GRefPtr<GstElement> src = adoptGRef(gst_pad_get_parent_element(pad)); + WebKitWebSrc* webkitSrc = WEBKIT_WEB_SRC(src.get()); gboolean result = FALSE; switch (GST_QUERY_TYPE(query)) { @@ -491,13 +512,19 @@ static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) gst_query_parse_duration(query, &format, NULL); - GST_DEBUG_OBJECT(src, "duration query in format %s", gst_format_get_name(format)); - if ((format == GST_FORMAT_BYTES) && (src->priv->size > 0)) { - gst_query_set_duration(query, format, src->priv->size); + GST_DEBUG_OBJECT(webkitSrc, "duration query in format %s", gst_format_get_name(format)); + if ((format == GST_FORMAT_BYTES) && (webkitSrc->priv->size > 0)) { + gst_query_set_duration(query, format, webkitSrc->priv->size); result = TRUE; } break; } + case GST_QUERY_URI: + { + gst_query_set_uri(query, webkitSrc->priv->uri); + result = TRUE; + break; + } default: break; } @@ -505,7 +532,6 @@ static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) if (!result) result = gst_pad_query_default(pad, query); - gst_object_unref(src); return result; } diff --git a/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp b/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp index a9ac186..7d08c36 100644 --- a/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp @@ -30,7 +30,6 @@ #include <InterfaceDefs.h> - namespace WebCore { Color::Color(const rgb_color& color) @@ -44,11 +43,4 @@ Color::operator rgb_color() const return make_color(red(), green(), blue(), alpha()); } - -Color focusRingColor() -{ - return Color(keyboard_navigation_color()); -} - } // namespace WebCore - diff --git a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index 4e17f94..b3f6c06 100644 --- a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -443,6 +443,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) notImplemented(); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp index 1fe3d28..1a56664 100644 --- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp +++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp @@ -49,13 +49,6 @@ static inline CGFloat roundCGFloat(CGFloat f) return static_cast<CGFloat>(round(f)); } -static inline CGFloat ceilCGFloat(CGFloat f) -{ - if (sizeof(CGFloat) == sizeof(float)) - return ceilf(static_cast<float>(f)); - return static_cast<CGFloat>(ceil(f)); -} - ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis) : m_font(*font) , m_run(run) @@ -69,7 +62,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru , m_currentRun(0) , m_glyphInCurrentRun(0) , m_characterInCurrentGlyph(0) - , m_finalRoundingWidth(0) , m_expansion(run.expansion()) , m_afterExpansion(true) , m_fallbackFonts(fallbackFonts) @@ -77,7 +69,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru , m_maxGlyphBoundingBoxX(numeric_limits<float>::min()) , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) - , m_lastRoundingGlyph(0) { if (!m_expansion) m_expansionPerOpportunity = 0; @@ -413,13 +404,11 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer) m_currentRun++; m_glyphInCurrentRun = 0; } - if (!ltr && m_numGlyphsSoFar == m_adjustedAdvances.size()) - m_runWidthSoFar += m_finalRoundingWidth; } void ComplexTextController::adjustGlyphsAndAdvances() { - CGFloat widthSinceLastRounding = 0; + CGFloat widthSinceLastCommit = 0; size_t runCount = m_complexTextRuns.size(); bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled(); for (size_t r = 0; r < runCount; ++r) { @@ -431,9 +420,8 @@ void ComplexTextController::adjustGlyphsAndAdvances() const CGSize* advances = complexTextRun.advances(); bool lastRun = r + 1 == runCount; - const UChar* cp = complexTextRun.characters(); - CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth()); bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances(); + const UChar* cp = complexTextRun.characters(); CGPoint glyphOrigin = CGPointZero; CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max(); bool isMonotonic = true; @@ -463,7 +451,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (ch == '\t' && m_run.allowTabs()) { float tabWidth = m_font.tabWidth(*fontData); - advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastRounding, tabWidth); + advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastCommit, tabWidth); } else if (ch == zeroWidthSpace || (Font::treatAsZeroWidthSpace(ch) && !treatAsSpace)) { advance.width = 0; glyph = fontData->spaceGlyph(); @@ -475,13 +463,6 @@ void ComplexTextController::adjustGlyphsAndAdvances() advance.width += fontData->syntheticBoldOffset(); - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all glyphs that - // match the width of the space glyph have the same width as the space glyph. - if (roundedAdvanceWidth == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding()) - advance.width = fontData->adjustedSpaceWidth(); - if (hasExtraSpacing) { // If we're a glyph with an advance, go ahead and add in letter-spacing. // That way we weed out zero width lurkers. This behavior matches the fast text code path. @@ -492,17 +473,14 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) { // Distribute the run's total expansion evenly over all expansion opportunities in the run. if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) { - float previousExpansion = m_expansion; if (!treatAsSpace && !m_afterExpansion) { // Take the expansion opportunity before this ideograph. m_expansion -= m_expansionPerOpportunity; - int expansion = roundf(previousExpansion) - roundf(m_expansion); - m_totalWidth += expansion; - m_adjustedAdvances.last().width += expansion; - previousExpansion = m_expansion; + m_totalWidth += m_expansionPerOpportunity; + m_adjustedAdvances.last().width += m_expansionPerOpportunity; } m_expansion -= m_expansionPerOpportunity; - advance.width += roundf(previousExpansion) - roundf(m_expansion); + advance.width += m_expansionPerOpportunity; m_afterExpansion = true; } else m_afterExpansion = false; @@ -514,33 +492,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() m_afterExpansion = false; } - // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so the following words will start on an integer boundary. - if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(ch)) - advance.width = ceilCGFloat(advance.width); - - // Check to see if the next character is a "rounding hack character", if so, adjust the - // width so that the total run width will be on an integer boundary. - if ((m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh)) || (m_run.applyRunRounding() && lastGlyph)) { - CGFloat totalWidth = widthSinceLastRounding + advance.width; - widthSinceLastRounding = ceilCGFloat(totalWidth); - CGFloat extraWidth = widthSinceLastRounding - totalWidth; - if (m_run.ltr()) - advance.width += extraWidth; - else { - if (m_lastRoundingGlyph) - m_adjustedAdvances[m_lastRoundingGlyph - 1].width += extraWidth; - else - m_finalRoundingWidth = extraWidth; - m_lastRoundingGlyph = m_adjustedAdvances.size() + 1; - } - m_totalWidth += widthSinceLastRounding; - widthSinceLastRounding = 0; - } else - widthSinceLastRounding += advance.width; + widthSinceLastCommit += advance.width; // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space. if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK))) @@ -564,7 +516,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (!isMonotonic) complexTextRun.setIsNonMonotonic(); } - m_totalWidth += widthSinceLastRounding; + m_totalWidth += widthSinceLastCommit; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h index 63f93a2..7373bfe 100644 --- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h +++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h @@ -60,9 +60,6 @@ public: float totalWidth() const { return m_totalWidth; } - // Extra width to the left of the leftmost glyph. - float finalRoundingWidth() const { return m_finalRoundingWidth; } - float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; } float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; } float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; } @@ -176,7 +173,6 @@ private: size_t m_currentRun; unsigned m_glyphInCurrentRun; unsigned m_characterInCurrentGlyph; - float m_finalRoundingWidth; float m_expansion; float m_expansionPerOpportunity; bool m_afterExpansion; @@ -187,8 +183,6 @@ private: float m_maxGlyphBoundingBoxX; float m_minGlyphBoundingBoxY; float m_maxGlyphBoundingBoxY; - - unsigned m_lastRoundingGlyph; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp index 865051d..eed49a5 100644 --- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp +++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp @@ -71,7 +71,7 @@ float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int float afterWidth = controller.runWidthSoFar(); if (run.rtl()) { - initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; + initialAdvance = controller.totalWidth() - afterWidth; for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) glyphBuffer.swap(i, end); } else diff --git a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp index 8b04ffa..fe2b33a 100644 --- a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp +++ b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp @@ -83,6 +83,11 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; + + // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may + // be non-CFEqual to fontData->platformData().cgFont(). + RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(fontData->platformData().ctFont(), 0)); + for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). @@ -93,7 +98,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. - if (CFEqual(fontData->platformData().cgFont(), runCGFont.get())) { + if (CFEqual(cgFont.get(), runCGFont.get())) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm index 6a4fa03..2383006 100644 --- a/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm +++ b/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm @@ -112,14 +112,14 @@ static NSColor* createPatternColor(NSString* name, NSColor* defaultColor, bool& } // WebKit on Mac is a standard platform component, so it must use the standard platform artwork for underline. -void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; // These are the same for misspelling or bad grammar. int patternHeight = cMisspellingLineThickness; - int patternWidth = cMisspellingLinePatternWidth; + float patternWidth = cMisspellingLinePatternWidth; bool usingDot; NSColor *patternColor; @@ -165,7 +165,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, // space between adjacent misspelled words was underlined. if (usingDot) { // allow slightly more considering that the pattern ends with a transparent pixel - int widthMod = width % patternWidth; + float widthMod = fmodf(width, patternWidth); if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; } diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h index 95ab456..80bc94e 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -177,6 +177,8 @@ private: virtual double maximumDurationToCacheMediaTime() const { return 5; } + virtual void setPrivateBrowsingMode(bool); + MediaPlayer* m_player; RetainPtr<QTMovie> m_qtMovie; RetainPtr<QTMovieView> m_qtMovieView; @@ -203,6 +205,7 @@ private: bool m_videoFrameHasDrawn; bool m_delayingLoad; bool m_isAllowedToRender; + bool m_privateBrowsing; #if DRAW_FRAME_RATE int m_frameCountWhilePlaying; double m_timeStartedPlaying; diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index 8b1fb92..ecb7d9f 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -200,7 +200,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQTKit::create(MediaPlayer* player void MediaPlayerPrivateQTKit::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player) @@ -224,6 +224,7 @@ MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player) , m_hasUnsupportedTracks(false) , m_videoFrameHasDrawn(false) , m_isAllowedToRender(false) + , m_privateBrowsing(false) #if DRAW_FRAME_RATE , m_frameCountWhilePlaying(0) , m_timeStartedPlaying(0) @@ -250,6 +251,7 @@ void MediaPlayerPrivateQTKit::createQTMovie(const String& url) [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute, [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute, [NSNumber numberWithBool:NO], QTMovieLoopsAttribute, + [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute", #ifndef BUILDING_ON_TIGER QTMovieApertureModeClean, QTMovieApertureModeAttribute, #endif @@ -552,14 +554,14 @@ MediaPlayerPrivateQTKit::MediaRenderingMode MediaPlayerPrivateQTKit::preferredRe if (!m_player->frameView() || !m_qtMovie) return MediaRenderingNone; - if (m_player->inMediaDocument() || !QTVideoRendererClass()) - return MediaRenderingMovieView; - #if USE(ACCELERATED_COMPOSITING) if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player)) return MediaRenderingMovieLayer; #endif + if (!QTVideoRendererClass()) + return MediaRenderingMovieView; + return MediaRenderingSoftwareRenderer; } @@ -1528,9 +1530,7 @@ void MediaPlayerPrivateQTKit::sawUnsupportedTracks() #if USE(ACCELERATED_COMPOSITING) bool MediaPlayerPrivateQTKit::supportsAcceleratedRendering() const { - // Also don't claim to support accelerated rendering when in the media document, as we will then render - // via QTMovieView which is already accelerated. - return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil && !m_player->inMediaDocument(); + return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil; } void MediaPlayerPrivateQTKit::acceleratedRenderingStateChanged() @@ -1577,6 +1577,15 @@ float MediaPlayerPrivateQTKit::mediaTimeForTimeValue(float timeValue) const return static_cast<float>(qttime.timeValue) / qttime.timeScale; } +void MediaPlayerPrivateQTKit::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_privateBrowsing = privateBrowsing; + if (!m_qtMovie) + return; + [m_qtMovie.get() setAttribute:[NSNumber numberWithBool:!privateBrowsing] forKey:@"QTMovieAllowPersistentCacheAttribute"]; +} + + } // namespace WebCore @implementation WebCoreMovieObserver diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.mm b/Source/WebCore/platform/graphics/mac/WebLayer.mm index 06ea9be..414a75f 100644 --- a/Source/WebCore/platform/graphics/mac/WebLayer.mm +++ b/Source/WebCore/platform/graphics/mac/WebLayer.mm @@ -61,6 +61,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA [NSGraphicsContext setCurrentContext:layerContext]; GraphicsContext graphicsContext(context); + graphicsContext.setIsCALayerContext(true); if (!layerContents->platformCALayerContentsOpaque()) { // Turn off font smoothing to improve the appearance of text rendered onto a transparent background. diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp index df45147..e09534e 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp @@ -87,6 +87,10 @@ bool Extensions3DOpenGL::supports(const String& name) // GL_OES_texture_half_float as available. if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float") return m_availableExtensions.contains("GL_ARB_texture_float"); + + // GL_OES_vertex_array_object + if (name == "GL_OES_vertex_array_object") + return m_availableExtensions.contains("GL_APPLE_vertex_array_object"); // Desktop GL always supports the standard derivative functions if (name == "GL_OES_standard_derivatives") @@ -127,6 +131,53 @@ void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, un ::glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height); } +Platform3DObject Extensions3DOpenGL::createVertexArrayOES() +{ + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + GLuint array = 0; + glGenVertexArraysAPPLE(1, &array); + return array; +#else + return 0; +#endif +} + +void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array) +{ + if (!array) + return; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + glDeleteVertexArraysAPPLE(1, &array); +#endif +} + +GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array) +{ + if (!array) + return GL_FALSE; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + return glIsVertexArrayAPPLE(array); +#else + return GL_FALSE; +#endif +} + +void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array) +{ + if (!array) + return; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + glBindVertexArrayAPPLE(array); +#endif +} + } // namespace WebCore #endif // ENABLE(WEBGL) diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h index 1941a42..9188507 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h @@ -43,7 +43,12 @@ public: virtual void ensureEnabled(const String&); virtual int getGraphicsResetStatusARB(); virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); - virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); private: // This class only needs to be instantiated by GraphicsContext3D implementations. diff --git a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp index 6466a9c..75dbadb 100644 --- a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp +++ b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp @@ -458,6 +458,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transformation) m_data->concatTransformation(transformation); } +void GraphicsContext::setCTM(const AffineTransform& transformation) +{ + if (paintingDisabled()) + return; + + m_data->setTransformation(transformation); +} + void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) { notImplemented(); diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp index 5238d46..dcea72f 100644 --- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp @@ -56,6 +56,32 @@ int Extensions3DQt::getGraphicsResetStatusARB() return GraphicsContext3D::NO_ERROR; } +void Extensions3DQt::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) +{ +} + +void Extensions3DQt::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) +{ +} + +Platform3DObject Extensions3DQt::createVertexArrayOES() +{ + return 0; +} + +void Extensions3DQt::deleteVertexArrayOES(Platform3DObject) +{ +} + +GC3Dboolean Extensions3DQt::isVertexArrayOES(Platform3DObject) +{ + return GL_FALSE; +} + +void Extensions3DQt::bindVertexArrayOES(Platform3DObject) +{ +} + } // namespace WebCore #endif // ENABLE(WEBGL) diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h index ae4b375..c67fbed 100644 --- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h +++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h @@ -38,6 +38,12 @@ public: virtual bool supports(const String&); virtual void ensureEnabled(const String&); virtual int getGraphicsResetStatusARB(); + virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); private: // This class only needs to be instantiated by GraphicsContext3D implementations. diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformData.h b/Source/WebCore/platform/graphics/qt/FontPlatformData.h index f268370..32e8a2d 100644 --- a/Source/WebCore/platform/graphics/qt/FontPlatformData.h +++ b/Source/WebCore/platform/graphics/qt/FontPlatformData.h @@ -24,142 +24,120 @@ #ifndef FontPlatformData_h #define FontPlatformData_h -#include <wtf/Forward.h> #include "FontDescription.h" #include "FontOrientation.h" #include <QFont> #include <QHash> +#include <wtf/Forward.h> +#include <wtf/RefCounted.h> namespace WebCore { -class FontPlatformDataPrivate { +class FontPlatformDataPrivate : public RefCounted<FontPlatformDataPrivate> { WTF_MAKE_NONCOPYABLE(FontPlatformDataPrivate); WTF_MAKE_FAST_ALLOCATED; public: FontPlatformDataPrivate() - : refCount(1) - , size(font.pixelSize()) + : size(font.pixelSize()) , bold(font.bold()) , oblique(false) - {} + , isDeletedValue(false) + { } FontPlatformDataPrivate(const float size, const bool bold, const bool oblique) - : refCount(1) - , size(size) + : size(size) , bold(bold) , oblique(oblique) - {} + , isDeletedValue(false) + { } FontPlatformDataPrivate(const QFont& font) - : refCount(1) - , font(font) + : font(font) , size(font.pixelSize()) , bold(font.bold()) , oblique(false) - {} - unsigned refCount; + , isDeletedValue(false) + { } + FontPlatformDataPrivate(WTF::HashTableDeletedValueType) + : isDeletedValue(true) + { } + QFont font; float size; bool bold : 1; bool oblique : 1; + bool isDeletedValue : 1; }; - - class FontPlatformData { WTF_MAKE_FAST_ALLOCATED; public: - FontPlatformData() { } FontPlatformData(float size, bool bold, bool oblique); - FontPlatformData(const FontPlatformData &); FontPlatformData(const FontDescription&, const AtomicString& familyName, int wordSpacing = 0, int letterSpacing = 0); FontPlatformData(const QFont& font) - : m_data(new FontPlatformDataPrivate(font)) - {} + : m_data(adoptRef(new FontPlatformDataPrivate(font))) + { } FontPlatformData(WTF::HashTableDeletedValueType) - : m_data(reinterpret_cast<FontPlatformDataPrivate*>(-1)) - {} - - ~FontPlatformData(); + : m_data(adoptRef(new FontPlatformDataPrivate())) + { + m_data->isDeletedValue = true; + } - FontPlatformData& operator=(const FontPlatformData&); bool operator==(const FontPlatformData&) const; bool isHashTableDeletedValue() const { - return m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1); - } - - static inline QFont::Weight toQFontWeight(FontWeight fontWeight) - { - switch (fontWeight) { - case FontWeight100: - case FontWeight200: - return QFont::Light; // QFont::Light == Weight of 25 - case FontWeight600: - return QFont::DemiBold; // QFont::DemiBold == Weight of 63 - case FontWeight700: - case FontWeight800: - return QFont::Bold; // QFont::Bold == Weight of 75 - case FontWeight900: - return QFont::Black; // QFont::Black == Weight of 87 - case FontWeight300: - case FontWeight400: - case FontWeight500: - default: - return QFont::Normal; // QFont::Normal == Weight of 50 - } + return m_data && m_data->isDeletedValue; } QFont font() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font; - return QFont(); + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return QFont(); + return m_data->font; } float size() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->size; - return 0.0f; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return 0; + return m_data->size; } QString family() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.family(); - return QString(); + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return QString(); + return m_data->font.family(); } bool bold() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->bold; - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->bold; } bool italic() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.italic(); - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->font.italic(); } bool smallCaps() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.capitalization() == QFont::SmallCaps; - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->font.capitalization() == QFont::SmallCaps; } int pixelSize() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) { - // WebKit allows font size zero but QFont does not. - if (!m_data->size) - return m_data->size; - return m_data->font.pixelSize(); - } - return 0; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return 0; + // WebCore allows a font size of zero, but QFont does not. + if (!m_data->size) + return 0; + return m_data->font.pixelSize(); } FontOrientation orientation() const { return Horizontal; } // FIXME: Implement. @@ -170,7 +148,7 @@ public: String description() const; #endif private: - FontPlatformDataPrivate* m_data; + RefPtr<FontPlatformDataPrivate> m_data; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp index 4c9eb32..185ae85 100644 --- a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2008 Holger Hans Peter Freyther Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ + Copyright (C) 2011 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 @@ -26,6 +27,27 @@ namespace WebCore { +static inline QFont::Weight toQFontWeight(FontWeight fontWeight) +{ + switch (fontWeight) { + case FontWeight100: + case FontWeight200: + return QFont::Light; // QFont::Light == Weight of 25 + case FontWeight600: + return QFont::DemiBold; // QFont::DemiBold == Weight of 63 + case FontWeight700: + case FontWeight800: + return QFont::Bold; // QFont::Bold == Weight of 75 + case FontWeight900: + return QFont::Black; // QFont::Black == Weight of 87 + case FontWeight300: + case FontWeight400: + case FontWeight500: + default: + return QFont::Normal; // QFont::Normal == Weight of 50 + } +} + static inline bool isEmptyValue(const float size, const bool bold, const bool oblique) { // this is the empty value by definition of the trait FontDataCacheKeyTraits @@ -34,20 +56,12 @@ static inline bool isEmptyValue(const float size, const bool bold, const bool ob FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) { - if (isEmptyValue(size, bold, oblique)) - m_data = 0; - else - m_data = new FontPlatformDataPrivate(size, bold, oblique); -} - -FontPlatformData::FontPlatformData(const FontPlatformData &other) : m_data(other.m_data) -{ - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) - ++m_data->refCount; + if (!isEmptyValue(size, bold, oblique)) + m_data = adoptRef(new FontPlatformDataPrivate(size, bold, oblique)); } FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, int wordSpacing, int letterSpacing) - : m_data(new FontPlatformDataPrivate()) + : m_data(adoptRef(new FontPlatformDataPrivate())) { QFont& font = m_data->font; int requestedSize = qRound(description.computedPixelSize()); @@ -70,38 +84,13 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato m_data->size = (!requestedSize) ? requestedSize : font.pixelSize(); } -FontPlatformData::~FontPlatformData() -{ - if (!m_data || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) - return; - --m_data->refCount; - if (!m_data->refCount) - delete m_data; -} - -FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) -{ - if (m_data == other.m_data) - return *this; - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) { - --m_data->refCount; - if (!m_data->refCount) - delete m_data; - } - m_data = other.m_data; - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) - ++m_data->refCount; - return *this; -} - bool FontPlatformData::operator==(const FontPlatformData& other) const { if (m_data == other.m_data) return true; - if (!m_data || !other.m_data - || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1) || other.m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) - return false; + if (!m_data || !other.m_data || m_data->isDeletedValue || other.m_data->isDeletedValue) + return false; const bool equals = (m_data->size == other.m_data->size && m_data->bold == other.m_data->bold @@ -114,7 +103,7 @@ unsigned FontPlatformData::hash() const { if (!m_data) return 0; - if (m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) + if (m_data->isDeletedValue) return 1; return qHash(m_data->font.toString()) ^ qHash(*reinterpret_cast<quint32*>(&m_data->size)) diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 8b87f5f..b849214 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -252,7 +252,7 @@ public: GLuint m_currentFbo; GLuint m_depthBuffer; QImage m_pixels; - ListHashSet<unsigned long> m_syntheticErrors; + ListHashSet<unsigned int> m_syntheticErrors; OwnPtr<Extensions3DQt> m_extensions; @@ -277,24 +277,6 @@ bool GraphicsContext3D::isGLES2Compliant() const #endif } -// Even with underlying GLES2 driver, the below flags should still be set to -// false if extentions exist (and they almost always do). -bool GraphicsContext3D::isGLES2NPOTStrict() const -{ - return false; -} - -bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const -{ - return false; -} - -int GraphicsContext3D::getGraphicsResetStatusARB() -{ - return NO_ERROR; -} - - GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) : m_attrs(attrs) , m_hostWindow(hostWindow) @@ -499,12 +481,12 @@ void* GraphicsContext3DInternal::getProcAddress(const String& proc) return 0; } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) +PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) { // This implementation doesn't currently support rendering directly to the HostWindow. if (renderStyle == RenderDirectlyToHostWindow) return 0; - OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow, false)); + RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, false)); return context->m_internal ? context.release() : 0; } @@ -1038,7 +1020,7 @@ GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture) return glIsTexture(texture); } -void GraphicsContext3D::lineWidth(double width) +void GraphicsContext3D::lineWidth(GC3Dfloat width) { m_internal->m_glWidget->makeCurrent(); glLineWidth(static_cast<float>(width)); @@ -1489,7 +1471,7 @@ void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, m_internal->getUniformiv(program, location, value); } -long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) +GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) { ASSERT(program); @@ -1620,7 +1602,7 @@ Extensions3D* GraphicsContext3D::getExtensions() { if (!m_internal->m_extensions) m_internal->m_extensions = adoptPtr(new Extensions3DQt); - return m_internal->m_extensions; + return m_internal->m_extensions.get(); } bool GraphicsContext3D::getImageData(Image* image, @@ -1637,13 +1619,13 @@ bool GraphicsContext3D::getImageData(Image* image, if (!nativePixmap) return false; - AlphaOp neededAlphaOp = kAlphaDoNothing; + AlphaOp neededAlphaOp = AlphaDoNothing; if (!premultiplyAlpha) // FIXME: must fetch the image data before the premultiplication step - neededAlphaOp = kAlphaDoUnmultiply; + neededAlphaOp = AlphaDoUnmultiply; QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32); outputVector.resize(nativeImage.byteCount()); - return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(), 0, + return packPixels(nativeImage.rgbSwapped().bits(), SourceFormatRGBA8, image->width(), image->height(), 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index bf2826c..9742755 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -555,8 +555,17 @@ void GraphicsContext::strokePath(const Path& path) boundingRect.inflate(pen.miterLimit() + pen.widthF()); QPainter* shadowPainter = shadow->beginShadowLayer(this, boundingRect); if (shadowPainter) { - shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255); - shadowPainter->strokePath(platformPath, pen); + if (m_state.strokeGradient) { + QBrush brush(*m_state.strokeGradient->platformGradient()); + brush.setTransform(m_state.strokeGradient->gradientSpaceTransform()); + QPen shadowPen(pen); + shadowPen.setBrush(brush); + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->strokePath(platformPath, shadowPen); + } else { + shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255); + shadowPainter->strokePath(platformPath, pen); + } shadow->endShadowLayer(this); } } else { @@ -769,6 +778,14 @@ ContextShadow* GraphicsContext::contextShadow() return &m_data->shadow; } +void GraphicsContext::clip(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + m_data->p()->setClipRect(rect, Qt::IntersectClip); +} + void GraphicsContext::clip(const FloatRect& rect) { if (paintingDisabled()) @@ -846,13 +863,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int drawFocusRingForPath(m_data->p(), path, color, m_data->antiAliasingForRectsAndLines); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool) { if (paintingDisabled()) return; - IntPoint startPoint = origin; - IntPoint endPoint = origin + IntSize(width, 0); + FloatPoint startPoint = origin; + FloatPoint endPoint = origin + FloatSize(width, 0); // If paintengine type is X11 to avoid artifacts // like bug https://bugs.webkit.org/show_bug.cgi?id=42248 @@ -872,10 +889,11 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool) } #endif // defined(Q_WS_X11) - drawLine(startPoint, endPoint); + // FIXME: Loss of precision here. Might consider rounding. + drawLine(IntPoint(startPoint.x(), startPoint.y()), IntPoint(endPoint.x(), endPoint.y())); } -void GraphicsContext::drawLineForTextChecking(const IntPoint&, int, TextCheckingLineStyle) +void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float, TextCheckingLineStyle) { if (paintingDisabled()) return; @@ -1204,6 +1222,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->p()->setWorldTransform(transform, true); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + m_data->p()->setWorldTransform(transform); +} + void GraphicsContext::setURLForRect(const KURL&, const IntRect&) { notImplemented(); diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index 0d7aa45..f3cfc47 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -54,7 +54,6 @@ #define GRAPHICS_LAYER_TILING_THRESHOLD 2000 #endif - #define QT_DEBUG_RECACHE 0 #define QT_DEBUG_CACHEDUMP 0 @@ -62,6 +61,8 @@ namespace WebCore { +static const int gMinimumPixmapCacheLimit = 2048; + #ifndef QT_NO_GRAPHICSEFFECT class MaskEffectQt : public QGraphicsEffect { public: @@ -207,6 +208,10 @@ public: virtual Color tiledBackingStoreBackgroundColor() const; #endif + static bool allowAcceleratedCompositingCache() { return QPixmapCache::cacheLimit() > gMinimumPixmapCacheLimit; } + + void drawLayerContent(QPainter*, const QRect&); + public slots: // We need to notify the client (ie. the layer compositor) when the animation actually starts. void notifyAnimationStarted(); @@ -381,6 +386,15 @@ const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const return this; } + +void GraphicsLayerQtImpl::drawLayerContent(QPainter* painter, const QRect& clipRect) +{ + painter->setClipRect(clipRect, Qt::IntersectClip); + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + GraphicsContext gc(painter); + m_layer->paintGraphicsLayerContents(gc, clipRect); +} + QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) { if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) @@ -630,12 +644,16 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte switch (m_currentContent.contentType) { case HTMLContentType: if (m_state.drawsContent) { - QPixmap backingStore; - // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). - if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) - backingStore = recache(QRegion(m_state.contentsRect)); - const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); - painter->drawPixmap(0, 0, backingStore); + if (!allowAcceleratedCompositingCache()) + drawLayerContent(painter, option->exposedRect.toRect()); + else { + QPixmap backingStore; + // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). + if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) + backingStore = recache(QRegion(m_state.contentsRect)); + const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); + painter->drawPixmap(0, 0, backingStore); + } } break; case PixmapContentType: @@ -837,7 +855,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform // Recache now: all the content is ready and we don't want to wait until the paint event. // We only need to do this for HTML content, there's no point in caching directly composited // content like images or solid rectangles. - if (m_pendingContent.contentType == HTMLContentType) + if (m_pendingContent.contentType == HTMLContentType && allowAcceleratedCompositingCache()) recache(m_pendingContent.regionToUpdate); #endif update(m_pendingContent.regionToUpdate.boundingRect()); diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp index fab4db1..547dabc 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp @@ -126,7 +126,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivatePhonon::create(MediaPlayer* playe void MediaPlayerPrivatePhonon::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index caf9c2d..001d45b 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -24,7 +24,6 @@ #include "GraphicsContext.h" #include "HTMLMediaElement.h" #include "HTMLVideoElement.h" -#include "QtNAMThreadSafeProxy.h" #include "NetworkingContext.h" #include "NotImplemented.h" #include "RenderVideo.h" @@ -66,7 +65,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQt::create(MediaPlayer* player) void MediaPlayerPrivateQt::registerMediaEngine(MediaEngineRegistrar registrar) { - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } void MediaPlayerPrivateQt::getSupportedTypes(HashSet<String> &supported) @@ -106,6 +105,7 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player) , m_composited(false) , m_queuedSeek(-1) , m_preload(MediaPlayer::Auto) + , m_suppressNextPlaybackChanged(false) { m_mediaPlayer->setVideoOutput(m_videoItem); m_videoScene->addItem(m_videoItem); @@ -187,7 +187,8 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) m_webCorePlayer->readyStateChanged(); } - const QUrl rUrl = QUrl(QString(url)); + KURL kUrl(ParsedURLString, url); + const QUrl rUrl = kUrl; const QString scheme = rUrl.scheme().toLower(); // Grab the client media element @@ -209,8 +210,8 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) if (manager) { // Set the cookies - QtNAMThreadSafeProxy managerProxy(manager); - QList<QNetworkCookie> cookies = managerProxy.cookiesForUrl(rUrl); + QNetworkCookieJar* jar = manager->cookieJar(); + QList<QNetworkCookie> cookies = jar->cookiesForUrl(rUrl); // Don't set the header if there are no cookies. // This prevents a warning from being emitted. @@ -239,6 +240,9 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) m_mediaPlayer->setMuted(element->muted()); m_mediaPlayer->setVolume(static_cast<int>(element->volume() * 100.0)); + // Don't send PlaybackChanged notification for pre-roll. + m_suppressNextPlaybackChanged = true; + // Setting a media source will start loading the media, but we need // to pre-roll as well to get video size-hints and buffer-status if (element->paused()) @@ -445,6 +449,11 @@ void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State state) m_mediaPlayer->setPosition(m_queuedSeek); m_queuedSeek = -1; } + + if (!m_suppressNextPlaybackChanged) + m_webCorePlayer->playbackStateChanged(); + else + m_suppressNextPlaybackChanged = false; } void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF& size) diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index e4133db..81cdd79 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -157,6 +157,7 @@ private: MediaPlayer::Preload m_preload; bool m_delayingLoad; String m_mediaUrl; + bool m_suppressNextPlaybackChanged; }; } diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp index 9e43558..5d0b302 100644 --- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp @@ -61,7 +61,6 @@ void SimpleFontData::platformGlyphInit() if (!m_platformData.size()) return; m_spaceGlyph = 0; - m_adjustedSpaceWidth = m_spaceWidth; determinePitch(); m_missingGlyphData.fontData = this; m_missingGlyphData.glyph = 0; diff --git a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp index a636d10..2aadc08 100644 --- a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp @@ -110,23 +110,14 @@ static void fillStops(const Gradient::ColorStop* stopData, } } -static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b) -{ - return a.stop < b.stop; -} - SkShader* Gradient::platformGradient() { if (m_gradient) return m_gradient; - // FIXME: This and compareStops() are also in Gradient.cpp and - // CSSGradientValue.cpp; probably should refactor in WebKit. - if (!m_stopsSorted) { - if (m_stops.size()) - std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); - m_stopsSorted = true; - } + sortStopsIfNecessary(); + ASSERT(m_stopsSorted); + size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); @@ -167,17 +158,23 @@ SkShader* Gradient::platformGradient() SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile); } + + if (aspectRatio() != 1) { + // CSS3 elliptical gradients: apply the elliptical scaling at the + // gradient center point. + m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); + m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); + m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); + ASSERT(m_p0 == m_p1); + } } else { SkPoint pts[2] = { m_p0, m_p1 }; - m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, - static_cast<int>(countUsed), tile); + m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile); } ASSERT(m_gradient); - SkMatrix matrix = m_gradientSpaceTransformation; m_gradient->setLocalMatrix(matrix); - return m_gradient; } diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 9f2ed32..00afd07 100644 --- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -436,6 +436,17 @@ void GraphicsContext::concatCTM(const AffineTransform& affine) platformContext()->canvas()->concat(affine); } +void GraphicsContext::setCTM(const AffineTransform& affine) +{ + if (paintingDisabled()) + return; + + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->setCTM(affine); + + platformContext()->canvas()->setMatrix(affine); +} + void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) @@ -595,7 +606,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint); } -void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -644,8 +655,8 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex } // Offset it vertically by 1 so that there's some space under the text. - SkScalar originX = SkIntToScalar(pt.x()); - SkScalar originY = SkIntToScalar(pt.y()) + 1; + SkScalar originX = WebCoreFloatToSkScalar(pt.x()); + SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1; // Make a shader for the bitmap with an origin of the box we'll draw. This // shader is refcounted and will have an initial refcount of 1. @@ -667,13 +678,13 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex SkRect rect; rect.set(originX, originY, - originX + SkIntToScalar(width), + originX + WebCoreFloatToSkScalar(width), originY + SkIntToScalar(misspellBitmap->height())); platformContext()->canvas()->drawRect(rect, paint); } -void GraphicsContext::drawLineForText(const IntPoint& pt, - int width, +void GraphicsContext::drawLineForText(const FloatPoint& pt, + float width, bool printing) { if (paintingDisabled()) @@ -686,9 +697,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt, int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); SkRect r; - r.fLeft = SkIntToScalar(pt.x()); - r.fTop = SkIntToScalar(pt.y()); - r.fRight = r.fLeft + SkIntToScalar(width); + r.fLeft = WebCoreFloatToSkScalar(pt.x()); + r.fTop = WebCoreFloatToSkScalar(pt.y()); + r.fRight = r.fLeft + WebCoreFloatToSkScalar(width); r.fBottom = r.fTop + SkIntToScalar(thickness); SkPaint paint; @@ -720,6 +731,7 @@ void GraphicsContext::fillPath(const Path& pathToFill) if (paintingDisabled()) return; + // FIXME: add support to GLES2Canvas for more than just solid fills. if (platformContext()->useGPU() && platformContext()->canAccelerate()) { platformContext()->prepareForHardwareDraw(); platformContext()->gpuCanvas()->fillPath(pathToFill); @@ -857,43 +869,7 @@ AffineTransform GraphicsContext::getCTM() const FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) { - // This logic is copied from GraphicsContextCG, eseidel 5/05/08 - - // It is not enough just to round to pixels in device space. The rotation - // part of the affine transform matrix to device space can mess with this - // conversion if we have a rotating image like the hands of the world clock - // widget. We just need the scale, so we get the affine transform matrix and - // extract the scale. - - const SkMatrix& deviceMatrix = platformContext()->canvas()->getTotalMatrix(); - if (deviceMatrix.isIdentity()) - return rect; - - float deviceScaleX = sqrtf(square(deviceMatrix.getScaleX()) - + square(deviceMatrix.getSkewY())); - float deviceScaleY = sqrtf(square(deviceMatrix.getSkewX()) - + square(deviceMatrix.getScaleY())); - - FloatPoint deviceOrigin(rect.x() * deviceScaleX, rect.y() * deviceScaleY); - FloatPoint deviceLowerRight((rect.x() + rect.width()) * deviceScaleX, - (rect.y() + rect.height()) * deviceScaleY); - - deviceOrigin.setX(roundf(deviceOrigin.x())); - deviceOrigin.setY(roundf(deviceOrigin.y())); - deviceLowerRight.setX(roundf(deviceLowerRight.x())); - deviceLowerRight.setY(roundf(deviceLowerRight.y())); - - // Don't let the height or width round to 0 unless either was originally 0 - if (deviceOrigin.y() == deviceLowerRight.y() && rect.height()) - deviceLowerRight.move(0, 1); - if (deviceOrigin.x() == deviceLowerRight.x() && rect.width()) - deviceLowerRight.move(1, 0); - - FloatPoint roundedOrigin(deviceOrigin.x() / deviceScaleX, - deviceOrigin.y() / deviceScaleY); - FloatPoint roundedLowerRight(deviceLowerRight.x() / deviceScaleX, - deviceLowerRight.y() / deviceScaleY); - return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); + return rect; } void GraphicsContext::scale(const FloatSize& size) diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp index 6318c21..0344086 100644 --- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp @@ -144,7 +144,8 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlo // Move to the start position (0 sweep means we add a single point). m_path->arcTo(oval, startDegrees, 0, false); // Draw the circle. - m_path->addOval(oval); + m_path->addOval(oval, anticlockwise ? + SkPath::kCCW_Direction : SkPath::kCW_Direction); // Force a moveTo the end position. m_path->arcTo(oval, startDegrees + sweepDegrees, 0, true); } else { diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 5e08b3c..eac5e4a 100644 --- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -688,7 +688,7 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths) paint.setStyle(SkPaint::kFill_Style); for (size_t i = paths.size() - 1; i < paths.size(); --i) { - paths[i].setFillType(SkPath::kInverseWinding_FillType); + paths[i].toggleInverseFillType(); m_canvas->drawPath(paths[i], paint); } @@ -821,7 +821,7 @@ void PlatformContextSkia::syncSoftwareCanvas() const if (!m_useGPU) { #if ENABLE(SKIA_GPU) if (m_gpuCanvas) - m_gpuCanvas->bindFramebuffer(); + m_gpuCanvas->context()->makeContextCurrent(); #endif return; } diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp index 5046c50..54aa35e 100644 --- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp +++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp @@ -38,10 +38,17 @@ #include "SkCanvas.h" #include "SkPaint.h" #include "SkShader.h" +#include "SkTemplates.h" +#include "SkTypeface.h" #include <wtf/ListHashSet.h> #include <wtf/Vector.h> +#if ENABLE(SKIA_TEXT) +// FIXME: a future role of skia will have this in a proper header +extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&); +#endif + namespace WebCore { struct CachedOutlineKey { @@ -273,6 +280,23 @@ static bool skiaDrawText(HFONT hfont, const GOFFSET* offsets, int numGlyphs) { +#if ENABLE(SKIA_TEXT) + SkASSERT(sizeof(WORD) == sizeof(uint16_t)); + + // Reserve space for 64 glyphs on the stack. If numGlyphs is larger, the array + // will dynamically allocate it space for numGlyph glyphs. + static const size_t kLocalGlyphMax = 64; + SkAutoSTArray<kLocalGlyphMax, SkPoint> posStorage(numGlyphs); + SkPoint* pos = posStorage.get(); + SkScalar x = point.fX; + SkScalar y = point.fY; + for (int i = 0; i < numGlyphs; i++) { + pos[i].set(x + (offsets ? offsets[i].du : 0), + y + (offsets ? offsets[i].dv : 0)); + x += SkIntToScalar(advances[i]); + } + canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint); +#else float x = point.fX, y = point.fY; for (int i = 0; i < numGlyphs; i++) { @@ -292,10 +316,31 @@ static bool skiaDrawText(HFONT hfont, x += advances[i]; } - +#endif return true; } +#if ENABLE(SKIA_TEXT) +static void setupPaintForFont(HFONT hfont, SkPaint* paint) +{ + // FIXME: + // Much of this logic could also happen in + // FontCustomPlatformData::fontPlatformData and be cached, + // allowing us to avoid talking to GDI at this point. + // + LOGFONT info; + GetObject(hfont, sizeof(info), &info); + int size = info.lfHeight; + if (size < 0) + size = -size; // We don't let GDI dpi-scale us (see SkFontHost_win.cpp). + paint->setTextSize(SkIntToScalar(size)); + + SkTypeface* face = SkCreateTypefaceFromLOGFONT(info); + paint->setTypeface(face); + SkSafeUnref(face); +} +#endif + bool paintSkiaText(GraphicsContext* context, HFONT hfont, int numGlyphs, @@ -314,6 +359,10 @@ bool paintSkiaText(GraphicsContext* context, SkPaint paint; platformContext->setupPaintForFilling(&paint); paint.setFlags(SkPaint::kAntiAlias_Flag); +#if ENABLE(SKIA_TEXT) + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + setupPaintForFont(hfont, &paint); +#endif bool didFill = false; if ((textMode & TextModeFill) && SkColorGetA(paint.getColor())) { diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h index 3e3995f..14431aa 100644 --- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h +++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h @@ -40,7 +40,7 @@ #include "VGUtils.h" #elif PLATFORM(QT) #include <QTransform> -#elif PLATFORM(SKIA) +#elif USE(SKIA) #include <SkMatrix.h> #elif PLATFORM(WX) && USE(WXGC) #include <wx/graphics.h> @@ -165,7 +165,7 @@ public: operator VGMatrix() const; #elif PLATFORM(QT) operator QTransform() const; -#elif PLATFORM(SKIA) +#elif USE(SKIA) operator SkMatrix() const; #elif PLATFORM(WX) && USE(WXGC) operator wxGraphicsMatrix() const; diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h index fa27c0e..adda46b 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h +++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h @@ -32,17 +32,17 @@ #include <wtf/FastAllocBase.h> #if PLATFORM(CA) -#include <QuartzCore/CATransform3D.h> +typedef struct CATransform3D CATransform3D; #endif #if PLATFORM(CG) -#include <CoreGraphics/CGAffineTransform.h> +typedef struct CGAffineTransform CGAffineTransform; #elif PLATFORM(CAIRO) #include <cairo.h> #elif PLATFORM(OPENVG) #include "VGUtils.h" #elif PLATFORM(QT) #include <QTransform> -#elif PLATFORM(SKIA) +#elif USE(SKIA) #include <SkMatrix.h> #elif PLATFORM(WX) && USE(WXGC) #include <wx/graphics.h> @@ -321,7 +321,7 @@ public: operator VGMatrix() const; #elif PLATFORM(QT) operator QTransform() const; -#elif PLATFORM(SKIA) +#elif USE(SKIA) operator SkMatrix() const; #elif PLATFORM(WX) && USE(WXGC) operator wxGraphicsMatrix() const; diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp index d3c6b58..d0bd4e9 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp @@ -184,7 +184,7 @@ static const Color& grammarPatternColor() { return grammarColor; } -void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -204,7 +204,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, // bounds (e.g. when at the edge of a view) and could make it appear that the // space between adjacent misspelled words was underlined. // allow slightly more considering that the pattern ends with a transparent pixel - int widthMod = width % patternWidth; + float widthMod = fmodf(width, patternWidth); if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp index bb22024..f2850e4 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp @@ -197,4 +197,13 @@ void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform) ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); } +void GraphicsContextPlatformPrivate::setCTM(const AffineTransform& transform) +{ + if (!m_hdc) + return; + + XFORM xform = transform.toTransformationMatrix(); + SetWorldTransform(m_hdc, &xform); +} + } diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index d47de2b..40fe1d1 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,7 +46,9 @@ #include "TimeRanges.h" #include "Timer.h" #include <AssertMacros.h> +#include <CoreGraphics/CGAffineTransform.h> #include <CoreGraphics/CGContext.h> +#include <QuartzCore/CATransform3D.h> #include <Wininet.h> #include <wtf/CurrentTime.h> #include <wtf/HashSet.h> @@ -151,7 +153,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQuickTimeVisualContext::create(Me void MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualContext(MediaPlayer* player) @@ -175,6 +177,7 @@ MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualConte #endif , m_visualContextClient(new MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient(this)) , m_delayingLoad(false) + , m_privateBrowsing(false) , m_preload(MediaPlayer::Auto) { } @@ -1244,6 +1247,13 @@ void MediaPlayerPrivateQuickTimeVisualContext::acceleratedRenderingStateChanged( setUpVideoRendering(); } +void MediaPlayerPrivateQuickTimeVisualContext::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_privateBrowsing = privateBrowsing; + if (m_movie) + m_movie->setPrivateBrowsingMode(m_privateBrowsing); +} + #endif diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index a12d79e..0dc97cd 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,6 +30,7 @@ #include "MediaPlayerPrivate.h" #include "Timer.h" +#include <CoreGraphics/CGAffineTransform.h> #include <wtf/Forward.h> #include <wtf/OwnPtr.h> #include <wtf/RetainPtr.h> @@ -153,6 +154,8 @@ private: void visualContextTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*); void retrieveCurrentImage(); + virtual void setPrivateBrowsingMode(bool); + class MovieClient; friend class MovieClient; OwnPtr<MovieClient> m_movieClient; @@ -196,6 +199,7 @@ private: bool m_newFrameAvailable; bool m_delayingLoad; String m_movieURL; + bool m_privateBrowsing; MediaPlayer::Preload m_preload; #if DRAW_FRAME_RATE double m_frameCountWhilePlaying; diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp index 07b7621..5156cd3 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp @@ -40,6 +40,9 @@ #include "SoftLinking.h" #include "TimeRanges.h" #include "Timer.h" +#include <CoreGraphics/CGColorSpace.h> +#include <CoreGraphics/CGContext.h> +#include <CoreGraphics/CGImage.h> #include <Wininet.h> #include <wtf/CurrentTime.h> #include <wtf/HashSet.h> @@ -76,7 +79,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) diff --git a/Source/WebCore/platform/graphics/win/QTMovie.cpp b/Source/WebCore/platform/graphics/win/QTMovie.cpp index 4cd8161..05fbb86 100644 --- a/Source/WebCore/platform/graphics/win/QTMovie.cpp +++ b/Source/WebCore/platform/graphics/win/QTMovie.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -96,6 +96,7 @@ public: CFURLRef m_currentURL; float m_timeToRestore; float m_rateToRestore; + bool m_privateBrowsing; #if !ASSERT_DISABLED bool m_scaleCached; #endif @@ -121,6 +122,7 @@ QTMoviePrivate::QTMoviePrivate() , m_timeToRestore(-1.0f) , m_rateToRestore(-1.0f) , m_disabled(false) + , m_privateBrowsing(false) #if !ASSERT_DISABLED , m_scaleCached(false) #endif @@ -466,8 +468,8 @@ void QTMovie::load(CFURLRef url, bool preservesPitch) m_private->m_loadState = 0; } - // Define a property array for NewMovieFromProperties. 8 should be enough for our needs. - QTNewMoviePropertyElement movieProps[8]; + // Define a property array for NewMovieFromProperties. + QTNewMoviePropertyElement movieProps[9]; ItemCount moviePropCount = 0; bool boolTrue = true; @@ -550,6 +552,14 @@ void QTMovie::load(CFURLRef url, bool preservesPitch) movieProps[moviePropCount].propStatus = 0; moviePropCount++; + bool allowCaching = !m_private->m_privateBrowsing; + movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation; + movieProps[moviePropCount].propID = 'pers'; + movieProps[moviePropCount].propValueSize = sizeof(allowCaching); + movieProps[moviePropCount].propValueAddress = &allowCaching; + movieProps[moviePropCount].propStatus = 0; + moviePropCount++; + ASSERT(moviePropCount <= WTF_ARRAY_LENGTH(movieProps)); m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie); @@ -846,6 +856,14 @@ void QTMovie::resetTransform() m_private->cacheMovieScale(); } +void QTMovie::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_private->m_privateBrowsing = privateBrowsing; + if (m_private->m_movie) { + bool allowCaching = !m_private->m_privateBrowsing; + QTSetMovieProperty(m_private->m_movie, 'cach', 'pers', sizeof(allowCaching), &allowCaching); + } +} bool QTMovie::initializeQuickTime() { diff --git a/Source/WebCore/platform/graphics/win/QTMovie.h b/Source/WebCore/platform/graphics/win/QTMovie.h index 5e4c4e7..e97d16d 100644 --- a/Source/WebCore/platform/graphics/win/QTMovie.h +++ b/Source/WebCore/platform/graphics/win/QTMovie.h @@ -117,6 +117,8 @@ public: long timeScale() const; + void setPrivateBrowsingMode(bool); + private: QTMoviePrivate* m_private; friend class QTMoviePrivate; diff --git a/Source/WebCore/platform/graphics/win/UniscribeController.cpp b/Source/WebCore/platform/graphics/win/UniscribeController.cpp index ebbed51..a850882 100644 --- a/Source/WebCore/platform/graphics/win/UniscribeController.cpp +++ b/Source/WebCore/platform/graphics/win/UniscribeController.cpp @@ -261,18 +261,13 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S return true; // Convert all chars that should be treated as spaces to use the space glyph. - // We also create a map that allows us to quickly go from space glyphs or rounding - // hack glyphs back to their corresponding characters. + // We also create a map that allows us to quickly go from space glyphs back to their corresponding characters. Vector<int> spaceCharacters(glyphs.size()); spaceCharacters.fill(-1); - Vector<int> roundingHackCharacters(glyphs.size()); - roundingHackCharacters.fill(-1); - Vector<int> roundingHackWordBoundaries(glyphs.size()); - roundingHackWordBoundaries.fill(-1); const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f; unsigned logicalSpaceWidth = fontData->spaceWidth() * cLogicalScale; - float roundedSpaceWidth = roundf(fontData->spaceWidth()); + float spaceWidth = fontData->spaceWidth(); for (int k = 0; k < len; k++) { UChar ch = *(str + k); @@ -286,21 +281,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S if (treatAsSpace) spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos; } - - if (Font::isRoundingHackCharacter(ch)) - roundingHackCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos; - - int boundary = k + m_currentCharacter + item.iCharPos; - if (boundary < m_run.length()) { - // When at the last character in the str, don't look one past the end for a rounding hack character. - // Instead look ahead to the first character of next item, if there is a next one. - if (k + 1 == len) { - if (i + 2 < m_items.size() // Check for at least 2 items remaining. The last item is a terminating item containing no characters. - && Font::isRoundingHackCharacter(*(cp + m_items[i + 1].iCharPos))) - roundingHackWordBoundaries[clusters[k]] = boundary; - } else if (Font::isRoundingHackCharacter(*(str + k + 1))) - roundingHackWordBoundaries[clusters[k]] = boundary; - } } // Populate our glyph buffer with this information. @@ -324,14 +304,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S advance += fontData->syntheticBoldOffset(); - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all glyphs that - // match the width of the space glyph have the same width as the space glyph. - if (roundedAdvance == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && - m_run.applyWordRounding()) - advance = fontData->adjustedSpaceWidth(); - if (hasExtraSpacing) { // If we're a glyph with an advance, go ahead and add in letter-spacing. // That way we weed out zero width lurkers. This behavior matches the fast text code path. @@ -350,9 +322,8 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S advance += m_padding; m_padding = 0; } else { - float previousPadding = m_padding; m_padding -= m_padPerSpace; - advance += roundf(previousPadding) - roundf(m_padding); + advance += m_padPerSpace; } } @@ -362,25 +333,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S } } - // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so the following words will start on an integer boundary. - int roundingHackIndex = roundingHackCharacters[k]; - if (m_run.applyWordRounding() && roundingHackIndex != -1) - advance = ceilf(advance); - - // Check to see if the next character is a "rounding hack character", if so, adjust the - // width so that the total run width will be on an integer boundary. - int position = m_currentCharacter + len; - bool lastGlyph = (k == glyphs.size() - 1) && (m_run.rtl() ? i == 0 : i == m_items.size() - 2) && (position >= m_end); - if ((m_run.applyWordRounding() && roundingHackWordBoundaries[k] != -1) || - (m_run.applyRunRounding() && lastGlyph)) { - float totalWidth = m_runWidthSoFar + advance; - advance += ceilf(totalWidth) - totalWidth; - } - m_runWidthSoFar += advance; // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer diff --git a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp index c3e6ce4..cd35ccb 100644 --- a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp @@ -88,9 +88,7 @@ TextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun : m_textRun(start, length, parentTextRun.allowTabs(), 0, 0 , parentTextRun.allowsTrailingExpansion() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion , parentTextRun.rtl() - , parentTextRun.directionalOverride() - , parentTextRun.applyRunRounding() - , parentTextRun.applyWordRounding()) + , parentTextRun.directionalOverride()) , m_offset(o) , m_spaces(0) { diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp index 7b1c27b..19683df 100644 --- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp @@ -206,11 +206,16 @@ public: m_transform.rotate(rad2deg(radians)); } - void concatCTM(const AffineTransform& transform) + void concatCTM(const AffineTransform& transform) { m_transform *= transform; } + void setCTM(const AffineTransform& transform) + { + m_transform = transform; + } + IntRect mapRect(const IntRect& rect) const { return m_transform.mapRect(rect); @@ -1016,18 +1021,18 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int DrawFocusRect(dc, &rect); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; StrokeStyle oldStyle = strokeStyle(); setStrokeStyle(SolidStroke); - drawLine(origin, origin + IntSize(width, 0)); + drawLine(roundedIntPoint(origin), roundedIntPoint(origin + FloatSize(width, 0))); setStrokeStyle(oldStyle); } -void GraphicsContext::drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle style) { notImplemented(); } @@ -1124,6 +1129,11 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->concatCTM(transform); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + m_data->setCTM(transform); +} + AffineTransform& GraphicsContext::affineTransform() { return m_data->m_transform; @@ -1520,7 +1530,7 @@ static inline bool isCharVisible(UChar c) return c && c != zeroWidthSpace; } -void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to) +void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to) { if (paintingDisabled() || !fillColor().alpha() || !m_data->m_opacity) return; diff --git a/Source/WebCore/platform/graphics/wx/FontWx.cpp b/Source/WebCore/platform/graphics/wx/FontWx.cpp index c48f3c7..782d328 100644 --- a/Source/WebCore/platform/graphics/wx/FontWx.cpp +++ b/Source/WebCore/platform/graphics/wx/FontWx.cpp @@ -139,7 +139,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F controller.advance(run.length()); startX += controller.runWidthSoFar() - afterWidth; #else - startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; + startX += controller.totalWidth() - afterWidth; for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) glyphBuffer.swap(i, end); #endif diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 991be79..47f3211 100644 --- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -336,17 +336,17 @@ void GraphicsContext::clipPath(const Path&, WindRule) notImplemented(); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; - IntPoint endPoint = origin + IntSize(width, 0); + FloatPoint endPoint = origin + FloatSize(width, 0); m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), wxSOLID)); m_data->context->DrawLine(origin.x(), origin.y(), endPoint.x(), endPoint.y()); } -void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style) { switch (style) { case TextCheckingSpellingLineStyle: @@ -494,6 +494,19 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) return; } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + +#if USE(WXGC) + wxGraphicsContext* gc = m_data->context->GetGraphicsContext(); + if (gc) + gc->SetTransform(transform); +#endif + return; +} + void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) |