diff options
Diffstat (limited to 'WebCore/platform/graphics/mac')
-rw-r--r-- | WebCore/platform/graphics/mac/Canvas3DLayer.h | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/Canvas3DLayer.mm | 11 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/ComplexTextController.cpp | 22 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/ComplexTextController.h | 10 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/FontComplexTextMac.cpp | 10 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/FontMac.mm | 37 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/FontPlatformData.h | 5 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/FontPlatformDataMac.mm | 12 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp | 254 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/GraphicsLayerCA.h | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/GraphicsLayerCA.mm | 35 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/ImageMac.mm | 1 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h | 10 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm | 36 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/MediaPlayerProxy.h | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/mac/SimpleFontDataMac.mm | 22 |
16 files changed, 394 insertions, 80 deletions
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.h b/WebCore/platform/graphics/mac/Canvas3DLayer.h index 122ef39..4609010 100644 --- a/WebCore/platform/graphics/mac/Canvas3DLayer.h +++ b/WebCore/platform/graphics/mac/Canvas3DLayer.h @@ -32,16 +32,18 @@ namespace WebCore { class GraphicsLayer; + class GraphicsContext3D; } @interface Canvas3DLayer : CAOpenGLLayer { WebCore::GraphicsLayer* m_layerOwner; + WebCore::GraphicsContext3D* m_context; CGLContextObj m_contextObj; GLuint m_texture; } -- (id)initWithContext:(CGLContextObj)context texture:(GLuint)texture; +- (id)initWithContext:(WebCore::GraphicsContext3D*)context; - (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace; diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.mm b/WebCore/platform/graphics/mac/Canvas3DLayer.mm index 59a7384..22a0a10 100644 --- a/WebCore/platform/graphics/mac/Canvas3DLayer.mm +++ b/WebCore/platform/graphics/mac/Canvas3DLayer.mm @@ -41,10 +41,11 @@ using namespace WebCore; @implementation Canvas3DLayer --(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture +-(id)initWithContext:(GraphicsContext3D*)context { - m_contextObj = context; - m_texture = texture; + m_context = context; + m_contextObj = static_cast<CGLContextObj>(context->platformGraphicsContext3D()); + m_texture = static_cast<GLuint>(context->platformTexture()); self = [super init]; return self; } @@ -70,8 +71,8 @@ using namespace WebCore; -(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { - CGLSetCurrentContext(m_contextObj); - glFinish(); + m_context->prepareTexture(); + CGLSetCurrentContext(glContext); CGRect frame = [self frame]; diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp index 543d885..b501293 100644 --- a/WebCore/platform/graphics/mac/ComplexTextController.cpp +++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp @@ -68,6 +68,10 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru , m_characterInCurrentGlyph(0) , m_finalRoundingWidth(0) , m_fallbackFonts(fallbackFonts) + , m_minGlyphBoundingBoxX(numeric_limits<float>::max()) + , m_maxGlyphBoundingBoxX(numeric_limits<float>::min()) + , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) + , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) , m_lastRoundingGlyph(0) { m_padding = m_run.padding(); @@ -394,7 +398,12 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer) // FIXME: Instead of dividing the glyph's advance equially between the characters, this // could use the glyph's "ligature carets". However, there is no Core Text API to get the // ligature carets. - m_runWidthSoFar += adjustedAdvance.width * (m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset); + if (glyphStartOffset == glyphEndOffset) { + // When there are multiple glyphs per character we need to advance by the full width of the glyph. + ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph); + m_runWidthSoFar += adjustedAdvance.width; + } else + m_runWidthSoFar += adjustedAdvance.width * (m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset); if (glyphEndOffset + complexTextRun.stringLocation() > m_currentCharacter) return; @@ -433,6 +442,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth()); bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances(); bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_padding) && !m_run.spacingDisabled(); + CGPoint glyphOrigin = CGPointZero; CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max(); bool isMonotonic = true; @@ -536,6 +546,16 @@ void ComplexTextController::adjustGlyphsAndAdvances() advance.height *= -1; m_adjustedAdvances.append(advance); m_adjustedGlyphs.append(glyph); + + GlyphMetrics glyphMetrics = fontData->metricsForGlyph(glyph); + glyphMetrics.boundingBox.move(glyphOrigin.x, glyphOrigin.y); + m_minGlyphBoundingBoxX = min(m_minGlyphBoundingBoxX, glyphMetrics.boundingBox.x()); + m_maxGlyphBoundingBoxX = max(m_maxGlyphBoundingBoxX, glyphMetrics.boundingBox.right()); + m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, glyphMetrics.boundingBox.y()); + m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, glyphMetrics.boundingBox.bottom()); + glyphOrigin.x += advance.width; + glyphOrigin.y += advance.height; + lastCharacterIndex = characterIndex; } if (!isMonotonic) diff --git a/WebCore/platform/graphics/mac/ComplexTextController.h b/WebCore/platform/graphics/mac/ComplexTextController.h index 53e8f7a..280327f 100644 --- a/WebCore/platform/graphics/mac/ComplexTextController.h +++ b/WebCore/platform/graphics/mac/ComplexTextController.h @@ -62,6 +62,11 @@ public: // 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; } + float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; } + private: class ComplexTextRun : public RefCounted<ComplexTextRun> { public: @@ -173,6 +178,11 @@ private: HashSet<const SimpleFontData*>* m_fallbackFonts; + float m_minGlyphBoundingBoxX; + float m_maxGlyphBoundingBoxX; + float m_minGlyphBoundingBoxY; + float m_maxGlyphBoundingBoxY; + unsigned m_lastRoundingGlyph; }; diff --git a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp index 0db2601..b7ed0e9 100644 --- a/WebCore/platform/graphics/mac/FontComplexTextMac.cpp +++ b/WebCore/platform/graphics/mac/FontComplexTextMac.cpp @@ -33,6 +33,8 @@ #include "SimpleFontData.h" #include <wtf/MathExtras.h> +using namespace std; + namespace WebCore { FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, @@ -83,9 +85,15 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F drawGlyphBuffer(context, glyphBuffer, run, startPoint); } -float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts) const +float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { ComplexTextController controller(this, run, true, fallbackFonts); + if (glyphOverflow) { + glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent()); + glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent()); + glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX())); + glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth())); + } return controller.totalWidth(); } diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm index bb9561e..87057fa 100644 --- a/WebCore/platform/graphics/mac/FontMac.mm +++ b/WebCore/platform/graphics/mac/FontMac.mm @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2006 Apple Computer, Inc. + * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -47,6 +47,28 @@ bool Font::canReturnFallbackFontsForComplexText() return true; } +static void showGlyphsWithAdvances(const FontPlatformData& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count) +{ + if (!font.isColorBitmapFont()) + CGContextShowGlyphsWithAdvances(context, glyphs, advances, count); +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + else { + if (!count) + return; + + Vector<CGPoint, 256> positions(count); + CGAffineTransform matrix = CGAffineTransformInvert(CGContextGetTextMatrix(context)); + positions[0] = CGPointZero; + for (size_t i = 1; i < count; ++i) { + CGSize advance = CGSizeApplyAffineTransform(advances[i - 1], matrix); + positions[i].x = positions[i - 1].x + advance.width; + positions[i].y = positions[i - 1].y + advance.height; + } + CTFontDrawGlyphs(toCTFontRef(font.font()), glyphs, positions.data(), count, context); + } +#endif +} + void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { CGContextRef cgContext = context->platformContext(); @@ -98,7 +120,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons CGContextSetFont(cgContext, platformData.cgFont()); CGAffineTransform matrix = CGAffineTransformIdentity; - if (drawFont) + if (drawFont && !platformData.isColorBitmapFont()) memcpy(&matrix, [drawFont matrix], sizeof(matrix)); matrix.b = -matrix.b; matrix.d = -matrix.d; @@ -112,13 +134,14 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons } else CGContextSetFontSize(cgContext, platformData.m_size); + IntSize shadowSize; int shadowBlur; Color shadowColor; ColorSpace fillColorSpace = context->fillColorSpace(); context->getShadow(shadowSize, shadowBlur, shadowColor); - bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur; + bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur && !platformData.isColorBitmapFont(); if (hasSimpleShadow) { // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing. context->clearShadow(); @@ -126,19 +149,19 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); context->setFillColor(shadowFillColor, fillColorSpace); CGContextSetTextPosition(cgContext, point.x() + shadowSize.width(), point.y() + shadowSize.height()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); if (font->syntheticBoldOffset()) { CGContextSetTextPosition(cgContext, point.x() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + shadowSize.height()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); } context->setFillColor(fillColor, fillColorSpace); } CGContextSetTextPosition(cgContext, point.x(), point.y()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); if (font->syntheticBoldOffset()) { CGContextSetTextPosition(cgContext, point.x() + font->syntheticBoldOffset(), point.y()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); + showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); } if (hasSimpleShadow) diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/mac/FontPlatformData.h index faf5f2e..23016e7 100644 --- a/WebCore/platform/graphics/mac/FontPlatformData.h +++ b/WebCore/platform/graphics/mac/FontPlatformData.h @@ -61,6 +61,7 @@ struct FontPlatformData { #ifdef BUILDING_ON_TIGER , m_cgFont(0) #endif + , m_isColorBitmapFont(false) { } @@ -73,6 +74,7 @@ struct FontPlatformData { , m_size(size) , m_font(0) , m_cgFont(cgFont) + , m_isColorBitmapFont(false) { } @@ -113,6 +115,7 @@ struct FontPlatformData { bool roundsGlyphAdvances() const; bool allowsLigatures() const; + bool isColorBitmapFont() const { return m_isColorBitmapFont; } #ifndef BUILDING_ON_TIGER CGFontRef cgFont() const { return m_cgFont.get(); } @@ -133,6 +136,8 @@ private: #else CGFontRef m_cgFont; // It is not necessary to refcount this, since either an NSFont owns it or some CachedFont has it referenced. #endif + + bool m_isColorBitmapFont; }; } diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm index 0118c8b..53b0282 100644 --- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm +++ b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm @@ -1,7 +1,7 @@ /* * This file is part of the internal font implementation. * - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,6 +33,11 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool synt : m_syntheticBold(syntheticBold) , m_syntheticOblique(syntheticOblique) , m_font(nsFont) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + , m_isColorBitmapFont(CTFontGetSymbolicTraits(toCTFontRef(nsFont)) & kCTFontColorGlyphsTrait) +#else + , m_isColorBitmapFont(false) +#endif { if (nsFont) CFRetain(nsFont); @@ -54,6 +59,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& f) m_size = f.m_size; m_cgFont = f.m_cgFont; m_atsuFontID = f.m_atsuFontID; + m_isColorBitmapFont = f.m_isColorBitmapFont; } FontPlatformData:: ~FontPlatformData() @@ -76,6 +82,7 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f) if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) CFRelease(m_font); m_font = f.m_font; + m_isColorBitmapFont = f.m_isColorBitmapFont; return *this; } @@ -96,6 +103,9 @@ void FontPlatformData::setFont(NSFont *font) m_cgFont = wkGetCGFontFromNSFont(font); m_atsuFontID = wkGetNSFontATSUFontId(font); #endif +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(font)) & kCTFontColorGlyphsTrait; +#endif } bool FontPlatformData::roundsGlyphAdvances() const diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp index 096cdbd..82c314e 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp @@ -30,14 +30,13 @@ #include "GraphicsContext3D.h" #include "CanvasObject.h" -#include "CString.h" #include "ImageBuffer.h" #include "NotImplemented.h" #include "WebGLActiveInfo.h" #include "WebGLArray.h" #include "WebGLBuffer.h" -#include "WebGLFramebuffer.h" #include "WebGLFloatArray.h" +#include "WebGLFramebuffer.h" #include "WebGLIntArray.h" #include "WebGLProgram.h" #include "WebGLRenderbuffer.h" @@ -46,7 +45,9 @@ #include "WebGLUnsignedByteArray.h" #include <CoreGraphics/CGBitmapContext.h> #include <OpenGL/CGLRenderers.h> +#include <OpenGL/gl.h> #include <wtf/UnusedParam.h> +#include <wtf/text/CString.h> namespace WebCore { @@ -75,28 +76,26 @@ static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBi attribs.append(static_cast<CGLPixelFormatAttribute>(0)); } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs) +PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) { - OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs)); + OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow)); return context->m_contextObj ? context.release() : 0; } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) - : m_attrs(attrs) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) + : m_currentWidth(0) + , m_currentHeight(0) + , m_attrs(attrs) , m_contextObj(0) , m_texture(0) , m_fbo(0) - , m_depthBuffer(0) -{ - // FIXME: we need to take into account the user's requested - // context creation attributes, in particular stencil and - // antialias, and determine which could and could not be honored - // based on the capabilities of the OpenGL implementation. - m_attrs.alpha = true; - m_attrs.depth = true; - m_attrs.stencil = false; - m_attrs.antialias = false; - m_attrs.premultipliedAlpha = true; + , m_depthStencilBuffer(0) + , m_boundFBO(0) + , m_multisampleFBO(0) + , m_multisampleDepthStencilBuffer(0) + , m_multisampleColorBuffer(0) +{ + UNUSED_PARAM(hostWindow); Vector<CGLPixelFormatAttribute> attribs; CGLPixelFormatObj pixelFormatObj = 0; @@ -145,6 +144,8 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) // Set the current context to the one given to us. CGLSetCurrentContext(m_contextObj); + validateAttributes(); + // create a texture to render into ::glGenTextures(1, &m_texture); ::glBindTexture(GL_TEXTURE_2D, m_texture); @@ -152,21 +153,27 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); ::glBindTexture(GL_TEXTURE_2D, 0); // create an FBO ::glGenFramebuffersEXT(1, &m_fbo); ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - ::glGenRenderbuffersEXT(1, &m_depthBuffer); - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); - ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 1, 1); - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - - ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); + m_boundFBO = m_fbo; + if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) + ::glGenRenderbuffersEXT(1, &m_depthStencilBuffer); + + // create an multisample FBO + if (m_attrs.antialias) { + ::glGenFramebuffersEXT(1, &m_multisampleFBO); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + m_boundFBO = m_multisampleFBO; + ::glGenRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attrs.stencil || m_attrs.depth) + ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + } + ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); ::glClearColor(0, 0, 0, 0); } @@ -174,14 +181,46 @@ GraphicsContext3D::~GraphicsContext3D() { if (m_contextObj) { CGLSetCurrentContext(m_contextObj); - ::glDeleteRenderbuffersEXT(1, & m_depthBuffer); ::glDeleteTextures(1, &m_texture); + if (m_attrs.antialias) { + ::glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attrs.stencil || m_attrs.depth) + ::glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + ::glDeleteFramebuffersEXT(1, &m_multisampleFBO); + } else { + if (m_attrs.stencil || m_attrs.depth) + ::glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer); + } ::glDeleteFramebuffersEXT(1, &m_fbo); CGLSetCurrentContext(0); CGLDestroyContext(m_contextObj); } } +void GraphicsContext3D::validateAttributes() +{ + const char* extensions = reinterpret_cast<const char*>(::glGetString(GL_EXTENSIONS)); + if (m_attrs.stencil) { + if (std::strstr(extensions, "GL_EXT_packed_depth_stencil")) { + if (!m_attrs.depth) + m_attrs.depth = true; + } else + m_attrs.stencil = false; + } + if (m_attrs.antialias) { + bool isValidVendor = true; + // Currently in Mac we only turn on antialias if vendor is NVIDIA. + const char* vendor = reinterpret_cast<const char*>(::glGetString(GL_VENDOR)); + if (!std::strstr(vendor, "NVIDIA")) + isValidVendor = false; + if (!isValidVendor || !std::strstr(extensions, "GL_EXT_framebuffer_multisample")) + m_attrs.antialias = false; + } + // FIXME: instead of enforcing premultipliedAlpha = true, implement the + // correct behavior when premultipliedAlpha = false is requested. + m_attrs.premultipliedAlpha = true; +} + void GraphicsContext3D::makeContextCurrent() { CGLSetCurrentContext(m_contextObj); @@ -206,24 +245,86 @@ void GraphicsContext3D::reshape(int width, int height) CGLSetCurrentContext(m_contextObj); + GLuint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + if (m_attrs.alpha) { + internalColorFormat = GL_RGBA8; + colorFormat = GL_RGBA; + } else { + internalColorFormat = GL_RGB8; + colorFormat = GL_RGB; + } + if (m_attrs.stencil || m_attrs.depth) { + // We don't allow the logic where stencil is required and depth is not. + // See GraphicsContext3D constructor. + if (m_attrs.stencil && m_attrs.depth) + internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT; + } + + bool mustRestoreFBO = false; + + // resize multisample FBO + if (m_attrs.antialias) { + GLint maxSampleCount; + ::glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); + GLint sampleCount = std::min(8, maxSampleCount); + if (sampleCount > maxSampleCount) + sampleCount = maxSampleCount; + if (m_boundFBO != m_multisampleFBO) { + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + mustRestoreFBO = true; + } + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + if (m_attrs.stencil || m_attrs.depth) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + ::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + if (m_attrs.stencil) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + if (m_attrs.depth) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + } + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { + // FIXME: cleanup. + notImplemented(); + } + } + + // resize regular FBO + if (m_boundFBO != m_fbo) { + mustRestoreFBO = true; + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } ::glBindTexture(GL_TEXTURE_2D, m_texture); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - ::glBindTexture(GL_TEXTURE_2D, 0); - - ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); - ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); - ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - + ::glTexImage2D(GL_TEXTURE_2D, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); ::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0); - ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); - GLenum status = ::glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + ::glBindTexture(GL_TEXTURE_2D, 0); + if (!m_attrs.antialias && (m_attrs.stencil || m_attrs.depth)) { + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); + if (m_attrs.stencil) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + if (m_attrs.depth) + ::glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + ::glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) { // FIXME: cleanup notImplemented(); } - ::glClear(GL_COLOR_BUFFER_BIT); + if (mustRestoreFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + + GLenum clearMask = GL_COLOR_BUFFER_BIT; + if (m_attrs.depth) + clearMask |= GL_DEPTH_BUFFER_BIT; + if (m_attrs.stencil) + clearMask |= GL_STENCIL_BUFFER_BIT; + ::glClear(clearMask); ::glFlush(); } @@ -237,6 +338,18 @@ static inline void ensureContext(CGLContextObj context) CGLSetCurrentContext(context); } +void GraphicsContext3D::prepareTexture() +{ + if (m_attrs.antialias) { + ensureContext(m_contextObj); + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + } + ::glFinish(); +} + void GraphicsContext3D::activeTexture(unsigned long texture) { ensureContext(m_contextObj); @@ -268,7 +381,15 @@ void GraphicsContext3D::bindBuffer(unsigned long target, WebGLBuffer* buffer) void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* buffer) { ensureContext(m_contextObj); - ::glBindFramebufferEXT(target, (buffer && buffer->object()) ? (GLuint) buffer->object() : m_fbo); + GLuint fbo; + if (buffer && buffer->object()) + fbo = (GLuint)buffer->object(); + else + fbo = (m_attrs.antialias ? m_multisampleFBO : m_fbo); + if (fbo != m_boundFBO) { + ::glBindFramebufferEXT(target, fbo); + m_boundFBO = fbo; + } } void GraphicsContext3D::bindRenderbuffer(unsigned long target, WebGLRenderbuffer* renderbuffer) @@ -384,13 +505,29 @@ void GraphicsContext3D::compileShader(WebGLShader* shader) void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) { ensureContext(m_contextObj); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } ::glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } void GraphicsContext3D::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height) { ensureContext(m_contextObj); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } ::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } void GraphicsContext3D::cullFace(unsigned long mode) @@ -476,7 +613,12 @@ void GraphicsContext3D::flush() void GraphicsContext3D::framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer* buffer) { ensureContext(m_contextObj); - ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer ? (GLuint) buffer->object() : 0); + GLuint renderbuffer = (buffer ? (GLuint) buffer->object() : 0); + if (attachment == DEPTH_STENCIL_ATTACHMENT) { + ::glFramebufferRenderbufferEXT(target, DEPTH_ATTACHMENT, renderbuffertarget, renderbuffer); + ::glFramebufferRenderbufferEXT(target, STENCIL_ATTACHMENT, renderbuffertarget, renderbuffer); + } else + ::glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer); } void GraphicsContext3D::framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture* texture, long level) @@ -665,20 +807,22 @@ void GraphicsContext3D::polygonOffset(double factor, double units) ::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units)); } -PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type) +void GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data) { + // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., + // all previous rendering calls should be done before reading pixels. ensureContext(m_contextObj); - - // FIXME: For now we only accept GL_UNSIGNED_BYTE/GL_RGBA. In reality OpenGL ES 2.0 accepts that pair and one other - // as specified by GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE. But for now we will - // not accept those. - // FIXME: Also, we should throw when an unacceptable value is passed - if (type != GL_UNSIGNED_BYTE || format != GL_RGBA) - return 0; - - RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4); - ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data()); - return array; + ::glFlush(); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) { + ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + ::glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + ::glFlush(); + } + ::glReadPixels(x, y, width, height, format, type, data); + if (m_attrs.antialias && m_boundFBO == m_multisampleFBO) + ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); } void GraphicsContext3D::releaseShaderCompiler() @@ -691,6 +835,10 @@ void GraphicsContext3D::releaseShaderCompiler() void GraphicsContext3D::renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height) { ensureContext(m_contextObj); + if (internalformat == DEPTH_STENCIL) + internalformat = GL_DEPTH24_STENCIL8_EXT; + else if (internalformat == DEPTH_COMPONENT16) + internalformat = GL_DEPTH_COMPONENT; ::glRenderbufferStorageEXT(target, internalformat, width, height); } @@ -986,6 +1134,8 @@ void GraphicsContext3D::getFloatv(unsigned long pname, float* value) void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value) { ensureContext(m_contextObj); + if (attachment == DEPTH_STENCIL_ATTACHMENT) + attachment = DEPTH_ATTACHMENT; // Or STENCIL_ATTACHMENT, either works. ::glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); } diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h index 5362562..49aebba 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h @@ -340,6 +340,7 @@ private: RetainPtr<WebAnimationDelegate> m_animationDelegate; + RetainPtr<CGImageRef> m_uncorrectedContentsImage; RetainPtr<CGImageRef> m_pendingContentsImage; struct LayerAnimation { diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm index 22e39f5..294c82f 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm @@ -34,7 +34,6 @@ #if ENABLE(3D_CANVAS) #import "Canvas3DLayer.h" #endif -#import "CString.h" #import "FloatConversion.h" #import "FloatRect.h" #import "Image.h" @@ -769,7 +768,17 @@ void GraphicsLayerCA::pauseAnimation(const String& keyframesName, double timeOff void GraphicsLayerCA::setContentsToImage(Image* image) { if (image) { - m_pendingContentsImage = image->nativeImageForCurrentFrame(); + CGImageRef newImage = image->nativeImageForCurrentFrame(); + if (!newImage) + return; + + // Check to see if the image changed; we have to do this because the call to + // CGImageCreateCopyWithColorSpace() below can create a new image every time. + if (m_uncorrectedContentsImage && m_uncorrectedContentsImage.get() == newImage) + return; + + m_uncorrectedContentsImage = newImage; + m_pendingContentsImage = newImage; CGColorSpaceRef colorSpace = CGImageGetColorSpace(m_pendingContentsImage.get()); static CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); @@ -783,6 +792,7 @@ void GraphicsLayerCA::setContentsToImage(Image* image) if (!m_contentsLayer) noteSublayersChanged(); } else { + m_uncorrectedContentsImage = 0; m_pendingContentsImage = 0; m_contentsLayerPurpose = NoContentsLayer; if (m_contentsLayer) @@ -1716,7 +1726,7 @@ void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* gr if (m_platformGraphicsContext3D != NullPlatformGraphicsContext3D && m_platformTexture != NullPlatform3DObject) { // create the inner 3d layer - m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:static_cast<CGLContextObj>(m_platformGraphicsContext3D) texture:static_cast<GLuint>(m_platformTexture)]); + m_contentsLayer.adoptNS([[Canvas3DLayer alloc] initWithContext:const_cast<GraphicsContext3D*>(graphicsContext3D)]); #ifndef NDEBUG [m_contentsLayer.get() setName:@"3D Layer"]; #endif @@ -1859,12 +1869,28 @@ void GraphicsLayerCA::setupAnimation(CAPropertyAnimation* propertyAnim, const An else if (anim->direction() == Animation::AnimationDirectionAlternate) repeatCount /= 2; + NSString* fillMode = 0; + switch (anim->fillMode()) { + case AnimationFillModeNone: + fillMode = kCAFillModeForwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash. + break; + case AnimationFillModeBackwards: + fillMode = kCAFillModeBoth; // Use "both" rather than "backwards" because the style system will remove the animation when it is finished. This avoids a flash. + break; + case AnimationFillModeForwards: + fillMode = kCAFillModeForwards; + break; + case AnimationFillModeBoth: + fillMode = kCAFillModeBoth; + break; + } + [propertyAnim setDuration:duration]; [propertyAnim setRepeatCount:repeatCount]; [propertyAnim setAutoreverses:anim->direction()]; [propertyAnim setRemovedOnCompletion:NO]; [propertyAnim setAdditive:additive]; - [propertyAnim setFillMode:@"extended"]; + [propertyAnim setFillMode:fillMode]; [propertyAnim setDelegate:m_animationDelegate.get()]; } @@ -2226,6 +2252,7 @@ void GraphicsLayerCA::setupContentsLayer(CALayer* contentsLayer) { // Turn off implicit animations on the inner layer. [contentsLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]]; + [contentsLayer setMasksToBounds:YES]; if (defaultContentsOrientation() == CompositingCoordinatesBottomUp) { CATransform3D flipper = { diff --git a/WebCore/platform/graphics/mac/ImageMac.mm b/WebCore/platform/graphics/mac/ImageMac.mm index 672c3c8..96b93be 100644 --- a/WebCore/platform/graphics/mac/ImageMac.mm +++ b/WebCore/platform/graphics/mac/ImageMac.mm @@ -30,6 +30,7 @@ #import "FoundationExtras.h" #import "GraphicsContext.h" #import "PlatformString.h" +#import "SharedBuffer.h" @interface WebCoreBundleFinder : NSObject @end diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h index 355aa68..2636aeb 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h @@ -59,7 +59,6 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface { public: static void registerMediaEngine(MediaEngineRegistrar); - ~MediaPlayerPrivate(); void repaint(); void loadStateChanged(); @@ -70,6 +69,7 @@ public: private: MediaPlayerPrivate(MediaPlayer*); + ~MediaPlayerPrivate(); // engine support static MediaPlayerPrivateInterface* create(MediaPlayer* player); @@ -89,9 +89,12 @@ private: void load(const String& url); void cancelLoad(); + void loadInternal(const String& url); + void resumeLoad(); void play(); void pause(); + void prepareToPlay(); bool paused() const; bool seeking() const; @@ -107,6 +110,8 @@ private: bool hasClosedCaptions() const; void setClosedCaptionsVisible(bool); + void setPreload(MediaPlayer::Preload); + MediaPlayer::NetworkState networkState() const { return m_networkState; } MediaPlayer::ReadyState readyState() const { return m_readyState; } @@ -172,6 +177,7 @@ private: RetainPtr<QTMovieView> m_qtMovieView; RetainPtr<QTVideoRendererWebKitOnly> m_qtVideoRenderer; RetainPtr<WebCoreMovieObserver> m_objcObserver; + String m_movieURL; float m_seekTo; Timer<MediaPlayerPrivate> m_seekTimer; MediaPlayer::NetworkState m_networkState; @@ -184,11 +190,13 @@ private: float m_cachedDuration; float m_timeToRestore; RetainPtr<QTMovieLayer> m_qtVideoLayer; + MediaPlayer::Preload m_preload; bool m_startedPlaying; bool m_isStreaming; bool m_visible; bool m_hasUnsupportedTracks; bool m_videoFrameHasDrawn; + bool m_delayingLoad; #if DRAW_FRAME_RATE int m_frameCountWhilePlaying; double m_timeStartedPlaying; diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index 2b90f7a..c837b51 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -211,6 +211,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) , m_reportedDuration(-1) , m_cachedDuration(-1) , m_timeToRestore(-1) + , m_preload(MediaPlayer::Auto) , m_startedPlaying(false) , m_isStreaming(false) , m_visible(false) @@ -549,8 +550,30 @@ QTTime MediaPlayerPrivate::createQTTime(float time) const return QTMakeTime(time * timeScale, timeScale); } +void MediaPlayerPrivate::resumeLoad() +{ + m_delayingLoad = false; + + if (m_movieURL) + loadInternal(m_movieURL); +} + void MediaPlayerPrivate::load(const String& url) { + m_movieURL = url; + + // If the element is not supposed to load any data return immediately because QTKit + // doesn't have API to throttle loading. + if (m_preload == MediaPlayer::None) { + m_delayingLoad = true; + return; + } + + loadInternal(url); +} + +void MediaPlayerPrivate::loadInternal(const String& url) +{ if (m_networkState != MediaPlayer::Loading) { m_networkState = MediaPlayer::Loading; m_player->networkStateChanged(); @@ -570,6 +593,12 @@ void MediaPlayerPrivate::load(const String& url) [m_objcObserver.get() setDelayCallbacks:NO]; } +void MediaPlayerPrivate::prepareToPlay() +{ + if (!m_qtMovie || m_delayingLoad) + resumeLoad(); +} + PlatformMedia MediaPlayerPrivate::platformMedia() const { PlatformMedia plaftformMedia = { m_qtMovie.get() }; @@ -910,6 +939,7 @@ void MediaPlayerPrivate::updateStates() loadState = QTMovieLoadStateError; if (loadState != QTMovieLoadStateError) { + wkQTMovieSelectPreferredAlternates(m_qtMovie.get()); cacheMovieScale(); MediaPlayer::MovieLoadType movieType = movieLoadType(); m_isStreaming = movieType == MediaPlayer::StoredStream || movieType == MediaPlayer::LiveStream; @@ -1437,6 +1467,12 @@ MediaPlayer::MovieLoadType MediaPlayerPrivate::movieLoadType() const return movieType; } +void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload) +{ + m_preload = preload; + if (m_delayingLoad && m_preload != MediaPlayer::None) + resumeLoad(); +} } // namespace WebCore diff --git a/WebCore/platform/graphics/mac/MediaPlayerProxy.h b/WebCore/platform/graphics/mac/MediaPlayerProxy.h index 6060484..cc7ec95 100644 --- a/WebCore/platform/graphics/mac/MediaPlayerProxy.h +++ b/WebCore/platform/graphics/mac/MediaPlayerProxy.h @@ -40,8 +40,8 @@ enum MediaPlayerProxyNotificationType { MediaPlayerNotificationStartUsingNetwork, MediaPlayerNotificationStopUsingNetwork, - MediaPlayerNotificationEnteredFullScreen, - MediaPlayerNotificationExitedFullScreen, + MediaPlayerNotificationEnteredFullscreen, + MediaPlayerNotificationExitedFullscreen, MediaPlayerNotificationReadyForInspection, MediaPlayerNotificationReadyForPlayback, diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm index 09947d8..562f56e 100644 --- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm @@ -407,17 +407,29 @@ void SimpleFontData::determinePitch() [name caseInsensitiveCompare:@"MonotypeCorsiva"] != NSOrderedSame; } -float SimpleFontData::platformWidthForGlyph(Glyph glyph) const +GlyphMetrics SimpleFontData::platformMetricsForGlyph(Glyph glyph, GlyphMetricsMode metricsMode) const { - NSFont* font = m_platformData.font(); - float pointSize = m_platformData.m_size; + NSFont* font = platformData().font(); + float pointSize = platformData().m_size; CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); CGSize advance; - if (!wkGetGlyphTransformedAdvances(m_platformData.cgFont(), font, &m, &glyph, &advance)) { + if (!wkGetGlyphTransformedAdvances(platformData().cgFont(), font, &m, &glyph, &advance)) { LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize); advance.width = 0; } - return advance.width + m_syntheticBoldOffset; + GlyphMetrics metrics; + metrics.horizontalAdvance = advance.width + m_syntheticBoldOffset; + if (metricsMode == GlyphBoundingBox) { +#ifndef BUILDING_ON_TIGER + CGRect boundingBox; + CGFontGetGlyphBBoxes(platformData().cgFont(), &glyph, 1, &boundingBox); + CGFloat scale = pointSize / unitsPerEm(); + metrics.boundingBox = CGRectApplyAffineTransform(boundingBox, CGAffineTransformMakeScale(scale, -scale)); + if (m_syntheticBoldOffset) + metrics.boundingBox.setWidth(metrics.boundingBox.width() + m_syntheticBoldOffset); +#endif + } + return metrics; } #if USE(ATSUI) |