summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/mac
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/mac')
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.h4
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.mm11
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp22
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.h10
-rw-r--r--WebCore/platform/graphics/mac/FontComplexTextMac.cpp10
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm37
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformData.h5
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformDataMac.mm12
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp254
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h1
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm35
-rw-r--r--WebCore/platform/graphics/mac/ImageMac.mm1
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h10
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm36
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerProxy.h4
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm22
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)