summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/chromium
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium')
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp28
-rw-r--r--Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h7
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp51
-rw-r--r--Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h6
-rw-r--r--Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm2
-rw-r--r--Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp19
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp3
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp30
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontLinux.cpp2
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h3
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp10
-rw-r--r--Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h11
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp394
-rw-r--r--Source/WebCore/platform/graphics/chromium/GLES2Canvas.h19
-rw-r--r--Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.cpp101
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerChromium.h38
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp313
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h61
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp148
-rw-r--r--Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h51
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp38
-rw-r--r--Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h13
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp17
-rw-r--r--Source/WebCore/platform/graphics/chromium/ShaderChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp6
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp227
-rw-r--r--Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h45
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp16
-rw-r--r--Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp80
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h61
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp4
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h2
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp27
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h62
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp84
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h60
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp173
-rw-r--r--Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h75
44 files changed, 1617 insertions, 694 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
index ad961aa..4cb119a 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -56,7 +56,7 @@ Canvas2DLayerChromium::~Canvas2DLayerChromium()
layerRendererContext()->deleteTexture(m_textureId);
}
-void Canvas2DLayerChromium::updateContentsIfDirty()
+void Canvas2DLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty || !m_drawingBuffer)
return;
diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
index a14cb98..81b118c 100644
--- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h
@@ -46,7 +46,7 @@ public:
static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner);
virtual ~Canvas2DLayerChromium();
virtual bool drawsContent() const { return true; }
- virtual void updateContentsIfDirty();
+ virtual void updateCompositorResources();
void setTextureChanged();
unsigned textureId() const;
@@ -55,8 +55,6 @@ public:
private:
explicit Canvas2DLayerChromium(DrawingBuffer*, GraphicsLayerChromium* owner);
DrawingBuffer* m_drawingBuffer;
-
- static unsigned m_shaderProgramId;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
index 0264868..f306207 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp
@@ -40,8 +40,6 @@
namespace WebCore {
-unsigned CanvasLayerChromium::m_shaderProgramId = 0;
-
CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
, m_textureChanged(true)
@@ -54,22 +52,18 @@ CanvasLayerChromium::~CanvasLayerChromium()
{
}
-void CanvasLayerChromium::draw()
+PassRefPtr<CCLayerImpl> CanvasLayerChromium::createCCLayerImpl()
{
- ASSERT(layerRenderer());
- 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));
- 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());
+ return CCCanvasLayerImpl::create(this);
+}
+
+void CanvasLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer);
+ canvasLayer->setTextureId(m_textureId);
+ canvasLayer->setPremultipliedAlpha(m_premultipliedAlpha);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
index ed3a06f..cb2ccc9 100644
--- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h
@@ -43,9 +43,9 @@ class CanvasLayerChromium : public LayerChromium {
public:
virtual ~CanvasLayerChromium();
- virtual void draw();
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
- typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
explicit CanvasLayerChromium(GraphicsLayerChromium* owner);
@@ -55,9 +55,6 @@ protected:
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 78f93d5..4ea9c92 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -66,7 +66,7 @@ void ContentLayerChromium::cleanupResources()
m_contentsTexture.clear();
}
-bool ContentLayerChromium::requiresClippedUpdateRect() const
+bool ContentLayerChromium::requiresClippedUpdateRect()
{
// To avoid allocating excessively large textures, switch into "large layer mode" if
// one of the layer's dimensions is larger than 2000 pixels or the size of
@@ -77,7 +77,7 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const
|| !layerRenderer()->checkTextureSize(bounds()));
}
-void ContentLayerChromium::updateContentsIfDirty()
+void ContentLayerChromium::paintContentsIfDirty()
{
RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
if (!backing || backing->paintingGoesToWindow())
@@ -93,34 +93,25 @@ void ContentLayerChromium::updateContentsIfDirty()
// 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 (!ccLayerImpl()->drawTransform().isIdentityOrTranslation()) {
- m_skipsDraw = true;
- return;
- }
-
// Calculate the region of this layer that is currently visible.
const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect();
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.
- ASSERT(layerOriginTransform.isInvertible());
-
+ // We compute the visible portion of the layer by back-mapping the current RenderSurface
+ // content area to the layer. To do that, we invert the drawing matrix of the layer
+ // and project the content area rectangle to it. If the layer transform is not invertible
+ // then we skip rendering the layer.
+ if (!layerOriginTransform.isInvertible()) {
+ m_skipsDraw = true;
+ return;
+ }
TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
- IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
+ FloatQuad mappedClipToLayer = targetToLayerMatrix.projectQuad(FloatRect(clipRect));
+ IntRect visibleRectInLayerCoords = mappedClipToLayer.enclosingBoundingBox();
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
- // to keep track of the offset in order to render correctly.
- IntRect visibleRectInSurfaceCoords = layerOriginTransform.mapRect(visibleRectInLayerCoords);
- m_layerCenterInSurfaceCoords = FloatRect(visibleRectInSurfaceCoords).center();
-
// If this is still too large to render, then skip the layer completely.
if (!layerRenderer()->checkTextureSize(visibleRectInLayerCoords.size())) {
m_skipsDraw = true;
@@ -256,9 +247,14 @@ void ContentLayerChromium::draw()
GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
if (requiresClippedUpdateRect()) {
- float m43 = ccLayerImpl()->drawTransform().m43();
- TransformationMatrix transform;
- transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43);
+ // Compute the offset between the layer's center point and the center of the visible portion
+ // of the layer.
+ FloatPoint visibleRectCenterOffset = FloatRect(m_visibleRectInLayerCoords).center();
+ visibleRectCenterOffset.move(-0.5 * bounds().width(), -0.5 * bounds().height());
+
+ TransformationMatrix transform = ccLayerImpl()->drawTransform();
+ transform.translate(visibleRectCenterOffset.x(), visibleRectCenterOffset.y());
+
drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
transform, m_visibleRectInLayerCoords.width(),
m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(),
@@ -273,6 +269,11 @@ void ContentLayerChromium::draw()
unreserveContentsTexture();
}
+void ContentLayerChromium::updateCompositorResources()
+{
+ updateTextureIfNeeded();
+}
+
void ContentLayerChromium::unreserveContentsTexture()
{
if (!m_skipsDraw && m_contentsTexture)
@@ -281,8 +282,6 @@ void ContentLayerChromium::unreserveContentsTexture()
void ContentLayerChromium::bindContentsTexture()
{
- updateTextureIfNeeded();
-
if (!m_skipsDraw && m_contentsTexture)
m_contentsTexture->bindTexture();
}
diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index 6f070c2..cf296ab 100644
--- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -50,7 +50,8 @@ public:
virtual ~ContentLayerChromium();
- virtual void updateContentsIfDirty();
+ virtual void paintContentsIfDirty();
+ virtual void updateCompositorResources();
virtual void unreserveContentsTexture();
virtual void bindContentsTexture();
@@ -63,7 +64,7 @@ protected:
explicit ContentLayerChromium(GraphicsLayerChromium* owner);
virtual void cleanupResources();
- bool requiresClippedUpdateRect() const;
+ bool requiresClippedUpdateRect();
void resizeUploadBuffer(const IntSize&);
virtual const char* layerTypeAsString() const { return "ContentLayer"; }
@@ -82,7 +83,6 @@ private:
PlatformCanvas m_canvas;
IntRect m_visibleRectInLayerCoords;
- FloatPoint m_layerCenterInSurfaceCoords;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
index 227fbe4..b442d53 100644
--- a/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
+++ b/Source/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
@@ -29,7 +29,7 @@
#import "config.h"
#import "CrossProcessFontLoading.h"
-#import "../graphics/cocoa/FontPlatformData.h"
+#import "../graphics/FontPlatformData.h"
#import "PlatformBridge.h"
#import <AppKit/NSFont.h>
#import <wtf/HashMap.h>
diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index d956841..e559edb 100644
--- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -46,10 +46,6 @@
namespace WebCore {
-#if ENABLE(SKIA_GPU)
-extern GrContext* GetGlobalGrContext();
-#endif
-
struct DrawingBufferInternal {
unsigned offscreenColorTexture;
#if USE(ACCELERATED_COMPOSITING)
@@ -91,6 +87,9 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
, m_multisampleFBO(0)
, m_multisampleColorBuffer(0)
, m_internal(new DrawingBufferInternal)
+#if ENABLE(SKIA_GPU)
+ , m_grContext(0)
+#endif
{
if (!m_context->getExtensions()->supports("GL_CHROMIUM_copy_texture_to_parent_texture")) {
m_context.clear();
@@ -137,7 +136,8 @@ void DrawingBuffer::publishToPlatformLayer()
// would insert a fence into the child command stream that the compositor could wait for.
m_context->makeContextCurrent();
#if ENABLE(SKIA_GPU)
- GetGlobalGrContext()->flush(false);
+ if (m_grContext)
+ m_grContext->flush(0);
#endif
static_cast<Extensions3DChromium*>(m_context->getExtensions())->copyTextureToParentTextureCHROMIUM(m_colorBuffer, parentTexture);
m_context->flush();
@@ -166,4 +166,13 @@ Platform3DObject DrawingBuffer::platformColorBuffer() const
return m_colorBuffer;
}
+#if ENABLE(SKIA_GPU)
+void DrawingBuffer::setGrContext(GrContext* context)
+{
+ // We just take a ptr without referencing it, as we require that we never outlive
+ // the SharedGraphicsContext3D object that is giving us the context.
+ m_grContext = context;
+}
+#endif
+
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index bbe6d62..598ae86 100644
--- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -153,7 +153,8 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
fontDescription.computedSize(),
(style & SkTypeface::kBold) && !tf->isBold(),
(style & SkTypeface::kItalic) && !tf->isItalic(),
- fontDescription.orientation());
+ fontDescription.orientation(),
+ fontDescription.textOrientation());
tf->unref();
return result;
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index e57a84c..3c254dc 100644
--- a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -196,7 +196,7 @@ class TransparencyAwareGlyphPainter : public TransparencyAwareFontPainter {
// left of m_point. We express it this way so that if we're using the Skia
// drawing path we can use floating-point positioning, even though we have
// to use integer positioning in the GDI path.
- bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, int startAdvance) const;
+ bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, float startAdvance) const;
private:
virtual IntRect estimateTextBounds();
@@ -256,11 +256,11 @@ IntRect TransparencyAwareGlyphPainter::estimateTextBounds()
bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
const WORD* glyphs,
const int* advances,
- int startAdvance) const
+ float startAdvance) const
{
if (!m_useGDI) {
SkPoint origin = m_point;
- origin.fX += startAdvance;
+ origin.fX += SkFloatToScalar(startAdvance);
return paintSkiaText(m_graphicsContext, m_font->platformData().hfont(),
numGlyphs, glyphs, advances, 0, &origin);
}
@@ -400,17 +400,25 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
Vector<WORD, kMaxBufferLength> glyphs;
Vector<int, kMaxBufferLength> advances;
int glyphIndex = 0; // The starting glyph of the current chunk.
- int curAdvance = 0; // How far from the left the current chunk is.
+
+ // In order to round all offsets to the correct pixel boundary, this code keeps track of the absolute position
+ // of each glyph in floating point units and rounds to integer advances at the last possible moment.
+
+ float horizontalOffset = point.x(); // The floating point offset of the left side of the current glyph.
+ int lastHorizontalOffsetRounded = lroundf(horizontalOffset); // The rounded offset of the left side of the last glyph rendered.
while (glyphIndex < numGlyphs) {
// How many chars will be in this chunk?
int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
glyphs.resize(curLen);
advances.resize(curLen);
- int curWidth = 0;
+ float currentWidth = 0;
for (int i = 0; i < curLen; ++i, ++glyphIndex) {
glyphs[i] = glyphBuffer.glyphAt(from + glyphIndex);
- advances[i] = static_cast<int>(glyphBuffer.advanceAt(from + glyphIndex));
+ horizontalOffset += glyphBuffer.advanceAt(from + glyphIndex);
+ advances[i] = lroundf(horizontalOffset) - lastHorizontalOffsetRounded;
+ lastHorizontalOffsetRounded += advances[i];
+ currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
// Bug 26088 - very large positive or negative runs can fail to
// render so we clamp the size here. In the specs, negative
@@ -420,15 +428,14 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
// -32830, so we give ourselves a little breathing room.
const int maxNegativeRun = -32768;
const int maxPositiveRun = 32768;
- if ((curWidth + advances[i] < maxNegativeRun) || (curWidth + advances[i] > maxPositiveRun))
+ if ((currentWidth + advances[i] < maxNegativeRun) || (currentWidth + advances[i] > maxPositiveRun))
advances[i] = 0;
- curWidth += advances[i];
}
// Actually draw the glyphs (with retry on failure).
bool success = false;
for (int executions = 0; executions < 2; ++executions) {
- success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], curAdvance);
+ success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], horizontalOffset - point.x() - currentWidth);
if (!success && executions == 0) {
// Ask the browser to load the font for us and retry.
PlatformBridge::ensureFontLoaded(font->platformData().hfont());
@@ -439,8 +446,6 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
if (!success)
LOG_ERROR("Unable to draw the glyphs after second attempt");
-
- curAdvance += curWidth;
}
}
@@ -509,8 +514,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// Uniscribe counts the coordinates from the upper left, while WebKit uses
// the baseline, so we have to subtract off the ascent.
- state.draw(graphicsContext, hdc, static_cast<int>(point.x()),
- static_cast<int>(point.y() - fontMetrics().ascent()), from, to);
+ state.draw(graphicsContext, hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), from, to);
context->canvas()->endPlatformPaint();
}
diff --git a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
index 823dbc9..3c4a494 100644
--- a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -98,7 +98,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkPoint* vPosBegin = storage2.get();
SkPoint* vPosEnd = storage3.get();
- bool isVertical = font->orientation() == Vertical;
+ bool isVertical = font->platformData().orientation() == Vertical;
for (int i = 0; i < numGlyphs; i++) {
SkScalar myWidth = SkFloatToScalar(adv[i].width());
pos[i].set(x, y);
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
index b6ebb2e..84edebc 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h
@@ -71,6 +71,7 @@ public:
float size() const { return m_size; }
FontOrientation orientation() const { return Horizontal; } // FIXME: Implement.
+ void setOrientation(FontOrientation) { } // FIXME: Implement.
unsigned hash() const
{
@@ -105,7 +106,7 @@ private:
HFONT hfont() const { return m_hfont; }
unsigned hash() const
{
- return WTF::StringHasher::createBlobHash<sizeof(HFONT)>(&m_hfont);
+ return StringHasher::hashMemory<sizeof(HFONT)>(&m_hfont);
}
bool operator==(const RefCountedHFONT& other) const
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 6f9009f..c3edfac 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -76,13 +76,14 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
, m_fakeBold(src.m_fakeBold)
, m_fakeItalic(src.m_fakeItalic)
, m_orientation(src.m_orientation)
+ , m_textOrientation(src.m_textOrientation)
, m_style(src.m_style)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
SkSafeRef(m_typeface);
}
-FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation)
+FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation, TextOrientation textOrientation)
: m_typeface(tf)
, m_family(family)
, m_textSize(textSize)
@@ -90,6 +91,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float tex
, m_fakeBold(fakeBold)
, m_fakeItalic(fakeItalic)
, m_orientation(orientation)
+ , m_textOrientation(textOrientation)
{
SkSafeRef(m_typeface);
querySystemForRenderStyle();
@@ -102,6 +104,8 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
, m_emSizeInFontUnits(src.m_emSizeInFontUnits)
, m_fakeBold(src.m_fakeBold)
, m_fakeItalic(src.m_fakeItalic)
+ , m_orientation(src.m_orientation)
+ , m_textOrientation(src.m_textOrientation)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
SkSafeRef(m_typeface);
@@ -134,6 +138,7 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
m_fakeItalic = src.m_fakeItalic;
m_harfbuzzFace = src.m_harfbuzzFace;
m_orientation = src.m_orientation;
+ m_textOrientation = src.m_textOrientation;
m_style = src.m_style;
m_emSizeInFontUnits = src.m_emSizeInFontUnits;
@@ -199,13 +204,14 @@ bool FontPlatformData::operator==(const FontPlatformData& a) const
&& m_fakeBold == a.m_fakeBold
&& m_fakeItalic == a.m_fakeItalic
&& m_orientation == a.m_orientation
+ && m_textOrientation == a.m_textOrientation
&& m_style == a.m_style;
}
unsigned FontPlatformData::hash() const
{
unsigned h = SkTypeface::UniqueID(m_typeface);
- h ^= 0x01010101 * ((static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
+ h ^= 0x01010101 * ((static_cast<int>(m_textOrientation) << 3) | (static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
// This memcpy is to avoid a reinterpret_cast that breaks strict-aliasing
// rules. Memcpy is generally optimized enough so that performance doesn't
diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
index d9ebb61..541aa86 100644
--- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
+++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
@@ -33,6 +33,7 @@
#include "FontOrientation.h"
#include "FontRenderStyle.h"
+#include "TextOrientation.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
#include <wtf/text/CString.h>
@@ -66,6 +67,8 @@ public:
, m_emSizeInFontUnits(0)
, m_fakeBold(false)
, m_fakeItalic(false)
+ , m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData()
@@ -75,6 +78,7 @@ public:
, m_fakeBold(false)
, m_fakeItalic(false)
, m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData(float textSize, bool fakeBold, bool fakeItalic)
@@ -84,10 +88,11 @@ public:
, m_fakeBold(fakeBold)
, m_fakeItalic(fakeItalic)
, m_orientation(Horizontal)
+ , m_textOrientation(TextOrientationVerticalRight)
{ }
FontPlatformData(const FontPlatformData&);
- FontPlatformData(SkTypeface*, const char* name, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation = Horizontal);
+ FontPlatformData(SkTypeface*, const char* name, float textSize, bool fakeBold, bool fakeItalic, FontOrientation = Horizontal, TextOrientation = TextOrientationVerticalRight);
FontPlatformData(const FontPlatformData& src, float textSize);
~FontPlatformData();
@@ -113,7 +118,8 @@ public:
int emSizeInFontUnits() const;
FontOrientation orientation() const { return m_orientation; }
-
+ void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
+
bool operator==(const FontPlatformData&) const;
FontPlatformData& operator=(const FontPlatformData&);
bool isHashTableDeletedValue() const { return m_typeface == hashTableDeletedFontValue(); }
@@ -161,6 +167,7 @@ private:
bool m_fakeBold;
bool m_fakeItalic;
FontOrientation m_orientation;
+ TextOrientation m_textOrientation;
FontRenderStyle m_style;
mutable RefPtr<RefCountedHarfbuzzFace> m_harfbuzzFace;
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index 2ff6b8b..cc5a060 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -62,29 +62,51 @@ typedef void (GLAPIENTRY *TESSCB)();
typedef WTF::Vector<float> FloatVector;
typedef WTF::Vector<double> DoubleVector;
+struct PathAndTransform {
+ PathAndTransform(const Path& p, const AffineTransform& t)
+ : path(p)
+ , transform(t)
+ {
+ }
+ Path path;
+ AffineTransform transform;
+};
+
struct GLES2Canvas::State {
State()
: m_fillColor(0, 0, 0, 255)
+ , m_shadowColor(0, 0, 0, 0)
, m_alpha(1.0f)
, m_compositeOp(CompositeSourceOver)
- , m_clippingEnabled(false)
+ , m_numClippingPaths(0)
+ , m_shadowOffset(0, 0)
+ , m_shadowBlur(0)
+ , m_shadowsIgnoreTransforms(false)
{
}
State(const State& other)
: m_fillColor(other.m_fillColor)
+ , m_shadowColor(other.m_shadowColor)
, m_alpha(other.m_alpha)
, m_compositeOp(other.m_compositeOp)
, m_ctm(other.m_ctm)
, m_clippingPaths() // Don't copy; clipping paths are tracked per-state.
- , m_clippingEnabled(other.m_clippingEnabled)
+ , m_numClippingPaths(other.m_numClippingPaths)
+ , m_shadowOffset(other.m_shadowOffset)
+ , m_shadowBlur(other.m_shadowBlur)
+ , m_shadowsIgnoreTransforms(other.m_shadowsIgnoreTransforms)
{
}
Color m_fillColor;
+ Color m_shadowColor;
float m_alpha;
CompositeOperator m_compositeOp;
AffineTransform m_ctm;
- WTF::Vector<Path> m_clippingPaths;
- bool m_clippingEnabled;
+ WTF::Vector<PathAndTransform> m_clippingPaths;
+ int m_numClippingPaths;
+ FloatSize m_shadowOffset;
+ float m_shadowBlur;
+ bool m_shadowsIgnoreTransforms;
// Helper function for applying the state's alpha value to the given input
// color to produce a new output color. The logic is the same as
@@ -100,7 +122,11 @@ struct GLES2Canvas::State {
int a = (c.alpha() * s) >> 8;
return Color(c.red(), c.green(), c.blue(), a);
}
-
+ bool shadowActive() const
+ {
+ return m_shadowColor.alpha() > 0 && (m_shadowBlur || m_shadowOffset.width() || m_shadowOffset.height());
+ }
+ bool clippingEnabled() { return m_numClippingPaths > 0; }
};
static inline FloatPoint operator*(const FloatPoint& f, float scale)
@@ -193,12 +219,8 @@ void GLES2Canvas::bindFramebuffer()
void GLES2Canvas::clearRect(const FloatRect& rect)
{
bindFramebuffer();
- if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) {
- 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);
- m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+ if (m_state->m_ctm.isIdentity() && !m_state->clippingEnabled()) {
+ scissorClear(rect.x(), rect.y(), rect.width(), rect.height());
} else {
save();
setCompositeOperation(CompositeClear);
@@ -207,35 +229,66 @@ void GLES2Canvas::clearRect(const FloatRect& rect)
}
}
+void GLES2Canvas::scissorClear(float x, float y, float width, float height)
+{
+ int intX = static_cast<int>(x + 0.5f);
+ int intY = static_cast<int>(y + 0.5f);
+ int intWidth = static_cast<int>(x + width + 0.5f) - intX;
+ int intHeight = static_cast<int>(y + height + 0.5f) - intY;
+ m_context->scissor(intX, m_size.height() - intHeight - intY, intWidth, intHeight);
+ m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+ m_context->clearColor(Color(RGBA32(0)));
+ m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+}
+
void GLES2Canvas::fillPath(const Path& path)
{
+ if (m_state->shadowActive()) {
+ beginShadowDraw();
+ fillPathInternal(path, m_state->m_shadowColor);
+ endShadowDraw(path.boundingRect());
+ }
+
+ bindFramebuffer();
m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->m_clippingEnabled);
- fillPath(path, m_state->applyAlpha(m_state->m_fillColor));
+ applyClipping(m_state->clippingEnabled());
+
+ fillPathInternal(path, m_state->applyAlpha(m_state->m_fillColor));
}
void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
+ if (m_state->shadowActive()) {
+ beginShadowDraw();
+ fillRectInternal(rect, m_state->m_shadowColor);
+ endShadowDraw(rect);
+ }
+
+ bindFramebuffer();
m_context->applyCompositeOperator(m_state->m_compositeOp);
- applyClipping(m_state->m_clippingEnabled);
- m_context->useQuadVertices();
+ applyClipping(m_state->clippingEnabled());
+
+ fillRectInternal(rect, color);
+}
+
+void GLES2Canvas::fillRect(const FloatRect& rect)
+{
+ fillRect(rect, m_state->applyAlpha(m_state->m_fillColor), ColorSpaceDeviceRGB);
+}
+void GLES2Canvas::fillRectInternal(const FloatRect& rect, const Color& color)
+{
AffineTransform matrix(m_flipMatrix);
matrix *= m_state->m_ctm;
matrix.translate(rect.x(), rect.y());
matrix.scale(rect.width(), rect.height());
+ m_context->useQuadVertices();
m_context->useFillSolidProgram(matrix, color);
-
- bindFramebuffer();
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
}
-void GLES2Canvas::fillRect(const FloatRect& rect)
-{
- fillRect(rect, m_state->applyAlpha(m_state->m_fillColor), ColorSpaceDeviceRGB);
-}
-
void GLES2Canvas::setFillColor(const Color& color, ColorSpace colorSpace)
{
m_state->m_fillColor = color;
@@ -246,6 +299,26 @@ void GLES2Canvas::setAlpha(float alpha)
m_state->m_alpha = alpha;
}
+void GLES2Canvas::setShadowColor(const Color& color, ColorSpace)
+{
+ m_state->m_shadowColor = color;
+}
+
+void GLES2Canvas::setShadowOffset(const FloatSize& offset)
+{
+ m_state->m_shadowOffset = offset;
+}
+
+void GLES2Canvas::setShadowBlur(float shadowBlur)
+{
+ m_state->m_shadowBlur = shadowBlur;
+}
+
+void GLES2Canvas::setShadowsIgnoreTransforms(bool shadowsIgnoreTransforms)
+{
+ m_state->m_shadowsIgnoreTransforms = shadowsIgnoreTransforms;
+}
+
void GLES2Canvas::translate(float x, float y)
{
m_state->m_ctm.translate(x, y);
@@ -275,12 +348,12 @@ void GLES2Canvas::clipPath(const Path& path)
{
bindFramebuffer();
checkGLError("bindFramebuffer");
- beginStencilDraw();
+ beginStencilDraw(GraphicsContext3D::INCR);
// Red is used so we can see it if it ends up in the color buffer.
Color red(255, 0, 0, 255);
- fillPath(path, red);
- m_state->m_clippingPaths.append(path);
- m_state->m_clippingEnabled = true;
+ fillPathInternal(path, red);
+ m_state->m_clippingPaths.append(PathAndTransform(path, m_state->m_ctm));
+ m_state->m_numClippingPaths++;
}
void GLES2Canvas::clipOut(const Path& path)
@@ -297,53 +370,48 @@ void GLES2Canvas::save()
void GLES2Canvas::restore()
{
ASSERT(!m_stateStack.isEmpty());
- bool hadClippingPaths = !m_state->m_clippingPaths.isEmpty();
- m_stateStack.removeLast();
- m_state = &m_stateStack.last();
- if (hadClippingPaths) {
- m_context->clear(GraphicsContext3D::STENCIL_BUFFER_BIT);
- beginStencilDraw();
- StateVector::const_iterator iter;
- for (iter = m_stateStack.begin(); iter < m_stateStack.end(); ++iter) {
- const State& state = *iter;
- const Vector<Path>& clippingPaths = state.m_clippingPaths;
- Vector<Path>::const_iterator pathIter;
- for (pathIter = clippingPaths.begin(); pathIter < clippingPaths.end(); ++pathIter) {
- // Red is used so we can see it if it ends up in the color buffer.
- Color red(255, 0, 0, 255);
- fillPath(*pathIter, red);
- }
+ const Vector<PathAndTransform>& clippingPaths = m_state->m_clippingPaths;
+ if (!clippingPaths.isEmpty()) {
+ beginStencilDraw(GraphicsContext3D::DECR);
+ WTF::Vector<PathAndTransform>::const_iterator pathIter;
+ for (pathIter = clippingPaths.begin(); pathIter < clippingPaths.end(); ++pathIter) {
+ m_state->m_ctm = pathIter->transform;
+ // Red is used so we can see it if it ends up in the color buffer.
+ Color red(255, 0, 0, 255);
+ fillPathInternal(pathIter->path, red);
}
}
+ m_stateStack.removeLast();
+ m_state = &m_stateStack.last();
}
void GLES2Canvas::drawTexturedRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
+ bindFramebuffer();
m_context->applyCompositeOperator(compositeOp);
applyClipping(false);
- m_context->useQuadVertices();
m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
- drawQuad(textureSize, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha);
+ drawTexturedQuad(textureSize, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha);
}
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
- drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp, m_state->m_clippingEnabled);
+ drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp, m_state->clippingEnabled());
}
void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp, bool clip)
{
+ bindFramebuffer();
m_context->applyCompositeOperator(compositeOp);
applyClipping(clip);
const TilingData& tiles = texture->tiles();
IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
- m_context->useQuadVertices();
m_context->setActiveTexture(GraphicsContext3D::TEXTURE0);
for (int y = tileIdxRect.y(); y <= tileIdxRect.maxY(); y++) {
@@ -367,13 +435,18 @@ void GLES2Canvas::drawTexturedRectTile(Texture* texture, int tile, const FloatRe
IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile);
- drawQuad(tileBoundsWithBorder.size(), srcRectClippedInTileSpace, dstRectIntersected, transform, alpha);
+ drawTexturedQuad(tileBoundsWithBorder.size(), srcRectClippedInTileSpace, dstRectIntersected, transform, alpha);
}
-void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+void GLES2Canvas::convolveRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, float imageIncrement[2], const float* kernel, int kernelWidth)
{
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
+
AffineTransform matrix(m_flipMatrix);
- matrix *= transform;
matrix.translate(dstRect.x(), dstRect.y());
matrix.scale(dstRect.width(), dstRect.height());
@@ -382,13 +455,79 @@ void GLES2Canvas::drawQuad(const IntSize& textureSize, const FloatRect& srcRect,
texMatrix.translate(srcRect.x(), srcRect.y());
texMatrix.scale(srcRect.width(), srcRect.height());
- bindFramebuffer();
+ m_context->useQuadVertices();
+ m_context->useConvolutionProgram(matrix, texMatrix, kernel, kernelWidth, imageIncrement);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+ checkGLError("glDrawArrays");
+}
+static float gauss(float x, float sigma)
+{
+ return exp(- (x * x) / (2.0f * sigma * sigma));
+}
+
+static void buildKernel(float sigma, float* kernel, int kernelWidth)
+{
+ float halfWidth = (kernelWidth - 1.0f) / 2.0f;
+ float sum = 0.0f;
+ for (int i = 0; i < kernelWidth; ++i) {
+ kernel[i] = gauss(i - halfWidth, sigma);
+ sum += kernel[i];
+ }
+ // Normalize the kernel
+ float scale = 1.0f / sum;
+ for (int i = 0; i < kernelWidth; ++i)
+ kernel[i] *= scale;
+}
+
+void GLES2Canvas::drawTexturedQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+{
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= transform;
+ matrix.translate(dstRect.x(), dstRect.y());
+ matrix.scale(dstRect.width(), dstRect.height());
+
+ AffineTransform texMatrix;
+ texMatrix.scale(1.0f / textureSize.width(), 1.0f / textureSize.height());
+ texMatrix.translate(srcRect.x(), srcRect.y());
+ texMatrix.scale(srcRect.width(), srcRect.height());
+
+ m_context->useQuadVertices();
m_context->useTextureProgram(matrix, texMatrix, alpha);
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
checkGLError("glDrawArrays");
}
+void GLES2Canvas::drawTexturedQuadMitchell(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
+{
+ static const float mitchellCoefficients[16] = {
+ 0.0f / 18.0f, 1.0f / 18.0f, 16.0f / 18.0f, 1.0f / 18.0f,
+ 0.0f / 18.0f, 9.0f / 18.0f, 0.0f / 18.0f, -9.0f / 18.0f,
+ -6.0f / 18.0f, 27.0f / 18.0f, -36.0f / 18.0f, 15.0f / 18.0f,
+ 7.0f / 18.0f, -21.0f / 18.0f, 21.0f / 18.0f, -7.0f / 18.0f,
+ };
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= transform;
+ matrix.translate(dstRect.x(), dstRect.y());
+ matrix.scale(dstRect.width(), dstRect.height());
+
+ float imageIncrement[2] = { 1.0f / textureSize.width(), 1.0f / textureSize.height() };
+
+ AffineTransform texMatrix;
+ texMatrix.scale(imageIncrement[0], imageIncrement[1]);
+ texMatrix.translate(srcRect.x(), srcRect.y());
+ texMatrix.scale(srcRect.width(), srcRect.height());
+
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST);
+
+ m_context->useQuadVertices();
+ m_context->useBicubicProgram(matrix, texMatrix, mitchellCoefficients, imageIncrement, alpha);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
+ checkGLError("glDrawArrays");
+}
+
void GLES2Canvas::setCompositeOperation(CompositeOperator op)
{
m_state->m_compositeOp = op;
@@ -554,12 +693,9 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig
*count = indices.size();
}
-void GLES2Canvas::fillPath(const Path& path, const Color& color)
+void GLES2Canvas::fillPathInternal(const Path& path, const Color& color)
{
if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) {
- bindFramebuffer();
- m_context->applyCompositeOperator(m_state->m_compositeOp);
-
m_pathCache.clear();
LoopBlinnPathProcessor processor;
processor.process(path, m_pathCache);
@@ -590,18 +726,18 @@ void GLES2Canvas::fillPath(const Path& path, const Color& color)
int count;
unsigned vertexBuffer, indexBuffer;
createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer);
+
+ AffineTransform matrix(m_flipMatrix);
+ matrix *= m_state->m_ctm;
+
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;
-
m_context->useFillSolidProgram(matrix, color);
checkGLError("useFillSolidProgram");
- bindFramebuffer();
m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0);
checkGLError("drawArrays");
@@ -613,7 +749,141 @@ void GLES2Canvas::fillPath(const Path& path, const Color& color)
}
}
-void GLES2Canvas::beginStencilDraw()
+FloatRect GLES2Canvas::flipRect(const FloatRect& rect)
+{
+ FloatRect flippedRect(rect);
+ flippedRect.setY(m_size.height() - rect.y());
+ flippedRect.setHeight(-rect.height());
+ return flippedRect;
+}
+
+void GLES2Canvas::clearBorders(const FloatRect& rect, int width)
+{
+ scissorClear(rect.x(), rect.y() - width, rect.width() + width, width);
+ scissorClear(rect.maxX(), rect.y(), width, rect.height() + width);
+ scissorClear(rect.x() - width, rect.maxY(), rect.width() + width, width);
+ scissorClear(rect.x() - width, rect.y() - width, width, rect.height() + width);
+}
+
+void GLES2Canvas::beginShadowDraw()
+{
+ float offsetX = m_state->m_shadowOffset.width();
+ float offsetY = m_state->m_shadowOffset.height();
+ save();
+ if (m_state->m_shadowsIgnoreTransforms) {
+ AffineTransform newCTM;
+ newCTM.translate(offsetX, -offsetY);
+ newCTM *= m_state->m_ctm;
+ m_state->m_ctm = newCTM;
+ } else
+ m_state->m_ctm.translate(offsetX, offsetY);
+
+ if (m_state->m_shadowBlur > 0) {
+ // Draw hard shadow to offscreen buffer 0.
+ DrawingBuffer* dstBuffer = m_context->getOffscreenBuffer(0, m_size);
+ dstBuffer->bind();
+ m_context->applyCompositeOperator(CompositeCopy);
+ applyClipping(false);
+ m_context->clearColor(Color(RGBA32(0)));
+ m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
+ } else {
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+ }
+}
+
+void GLES2Canvas::endShadowDraw(const FloatRect& boundingBox)
+{
+ if (m_state->m_shadowBlur > 0) {
+ // Buffer 0 contains the primitive drawn with a hard shadow.
+ DrawingBuffer* srcBuffer = m_context->getOffscreenBuffer(0, m_size);
+ DrawingBuffer* dstBuffer = m_context->getOffscreenBuffer(1, m_size);
+
+ float sigma = m_state->m_shadowBlur * 0.333333f;
+ FloatRect shadowBoundingBox(m_state->m_ctm.mapRect(boundingBox));
+ FloatRect rect(FloatPoint(0, 0), m_size);
+ FloatRect srcRect(shadowBoundingBox);
+
+ int scaleFactor = 1;
+ while (sigma > cMaxSigma) {
+ srcRect.scale(0.5f);
+ scaleFactor *= 2;
+ sigma *= 0.5f;
+ }
+ srcRect = enclosingIntRect(srcRect);
+ srcRect.scale(scaleFactor);
+ for (int i = 1; i < scaleFactor; i *= 2) {
+ dstBuffer->bind();
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, srcBuffer->colorBuffer());
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ FloatRect dstRect(srcRect);
+ dstRect.scale(0.5f);
+ // Clear out 1 pixel border for linear filtering.
+ clearBorders(dstRect, 1);
+ drawTexturedQuad(srcBuffer->size(), flipRect(srcRect), dstRect, AffineTransform(), 1.0);
+ srcRect = dstRect;
+ std::swap(srcBuffer, dstBuffer);
+ }
+
+ int halfWidth = static_cast<int>(sigma * 3.0f);
+ int kernelWidth = halfWidth * 2 + 1;
+ OwnArrayPtr<float> kernel = adoptArrayPtr(new float[kernelWidth]);
+ buildKernel(sigma, kernel.get(), kernelWidth);
+
+ if (scaleFactor > 1) {
+ scissorClear(srcRect.maxX(), srcRect.y(), kernelWidth, srcRect.height());
+ scissorClear(srcRect.x() - kernelWidth, srcRect.y(), kernelWidth, srcRect.height());
+ }
+
+ // Blur in X offscreen.
+ dstBuffer->bind();
+ srcRect.inflateX(halfWidth);
+ srcRect.intersect(rect);
+ float imageIncrementX[2] = {1.0f / srcBuffer->size().width(), 0.0f};
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementX, kernel.get(), kernelWidth);
+
+ if (scaleFactor > 1) {
+ scissorClear(srcRect.x(), srcRect.maxY(), srcRect.width(), kernelWidth);
+ scissorClear(srcRect.x(), srcRect.y() - kernelWidth, srcRect.width(), kernelWidth);
+ }
+ srcRect.inflateY(halfWidth);
+ srcRect.intersect(rect);
+ std::swap(srcBuffer, dstBuffer);
+
+ float imageIncrementY[2] = {0.0f, 1.0f / srcBuffer->size().height()};
+ if (scaleFactor > 1) {
+ // Blur in Y offscreen.
+ dstBuffer->bind();
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementY, kernel.get(), kernelWidth);
+ // Clear out 2 pixel border for bicubic filtering.
+ clearBorders(srcRect, 2);
+ std::swap(srcBuffer, dstBuffer);
+
+ // Upsample srcBuffer -> main framebuffer using bicubic filtering.
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, srcBuffer->colorBuffer());
+ FloatRect dstRect = srcRect;
+ dstRect.scale(scaleFactor);
+ drawTexturedQuadMitchell(srcBuffer->size(), flipRect(srcRect), dstRect, AffineTransform(), 1.0);
+ } else {
+ // Blur in Y directly to framebuffer.
+ bindFramebuffer();
+ m_context->applyCompositeOperator(m_state->m_compositeOp);
+ applyClipping(m_state->clippingEnabled());
+
+ convolveRect(srcBuffer->colorBuffer(), srcBuffer->size(), flipRect(srcRect), srcRect, imageIncrementY, kernel.get(), kernelWidth);
+ }
+ }
+ restore();
+}
+
+void GLES2Canvas::beginStencilDraw(unsigned op)
{
// Turn on stencil test.
m_context->enableStencil(true);
@@ -624,9 +894,7 @@ void GLES2Canvas::beginStencilDraw()
checkGLError("stencilFunc");
// All writes incremement the stencil buffer.
- m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::INCR,
- GraphicsContext3D::INCR,
- GraphicsContext3D::INCR);
+ m_context->graphicsContext3D()->stencilOp(op, op, op);
checkGLError("stencilOp");
}
@@ -635,7 +903,7 @@ void GLES2Canvas::applyClipping(bool enable)
m_context->enableStencil(enable);
if (enable) {
// Enable drawing only where stencil is non-zero.
- m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::EQUAL, m_state->m_clippingPaths.size() % 256, 1);
+ m_context->graphicsContext3D()->stencilFunc(GraphicsContext3D::EQUAL, m_state->m_numClippingPaths, -1);
checkGLError("stencilFunc");
// Keep all stencil values the same.
m_context->graphicsContext3D()->stencilOp(GraphicsContext3D::KEEP,
diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
index 8887a16..f6a8bcf 100644
--- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -64,6 +64,10 @@ public:
void clearRect(const FloatRect&);
void setFillColor(const Color&, ColorSpace);
void setAlpha(float alpha);
+ void setShadowColor(const Color&, ColorSpace);
+ void setShadowOffset(const FloatSize&);
+ void setShadowBlur(float);
+ void setShadowsIgnoreTransforms(bool);
void setCompositeOperation(CompositeOperator);
void translate(float x, float y);
void rotate(float angleInRadians);
@@ -96,12 +100,21 @@ public:
DrawingBuffer* drawingBuffer() const { return m_drawingBuffer; }
private:
+ void scissorClear(float x, float y, float width, float height);
void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
- void drawQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void drawTexturedQuad(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void drawTexturedQuadMitchell(const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
+ void convolveRect(unsigned texture, const IntSize& textureSize, const FloatRect& srcRect, const FloatRect& dstRect, float imageIncrement[2], const float* kernel, int kernelWidth);
+
void applyCompositeOperator(CompositeOperator);
void createVertexBufferFromPath(const Path&, int* count, unsigned* vertexBuffer, unsigned* indexBuffer);
- void fillPath(const Path&, const Color&);
- void beginStencilDraw();
+ void fillPathInternal(const Path&, const Color&);
+ void fillRectInternal(const FloatRect&, const Color&);
+ FloatRect flipRect(const FloatRect&);
+ void clearBorders(const FloatRect&, int width);
+ void beginShadowDraw();
+ void endShadowDraw(const FloatRect& boundingBox);
+ void beginStencilDraw(unsigned op);
void applyClipping(bool enable);
void checkGLError(const char* header);
diff --git a/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
index ee2b5ab..cfc1754 100644
--- a/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
@@ -36,8 +36,8 @@
#include "GlyphPageTreeNode.h"
#include "PlatformBridge.h"
#include "SimpleFontData.h"
+#include "SystemInfo.h"
#include "UniscribeHelperTextRun.h"
-#include "WindowsVersion.h"
namespace WebCore {
@@ -134,7 +134,7 @@ static bool fillBMPGlyphs(unsigned offset,
bool haveGlyphs = false;
int invalidGlyph = 0xFFFF;
const DWORD cffTableTag = 0x20464643; // 4-byte identifier for OpenType CFF table ('CFF ').
- if (!isVistaOrNewer() && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
+ if ((windowsVersion() < WindowsVista) && !(tm.tmPitchAndFamily & TMPF_TRUETYPE) && (GetFontData(dc, cffTableTag, 0, 0, 0) == GDI_ERROR))
invalidGlyph = 0x1F;
Glyph spaceGlyph = 0; // Glyph for a space. Lazily filled.
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
index 7c42366..60c1332 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp
@@ -60,7 +60,7 @@ void ImageLayerChromium::setContents(Image* contents)
setNeedsDisplay();
}
-void ImageLayerChromium::updateContentsIfDirty()
+void ImageLayerChromium::paintContentsIfDirty()
{
ASSERT(layerRenderer());
@@ -68,7 +68,7 @@ void ImageLayerChromium::updateContentsIfDirty()
if (requiresClippedUpdateRect()) {
// Use the base version of updateContents which draws a subset of the
// image to a bitmap, as the pixel contents can't be uploaded directly.
- ContentLayerChromium::updateContentsIfDirty();
+ ContentLayerChromium::paintContentsIfDirty();
return;
}
diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
index cc9064d..6addabc 100644
--- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h
@@ -50,7 +50,7 @@ class ImageLayerChromium : public ContentLayerChromium {
public:
static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0);
- virtual void updateContentsIfDirty();
+ virtual void paintContentsIfDirty();
virtual bool drawsContent() const { return m_contents; }
void setContents(Image* image);
diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 95b7386..bc28239 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -62,6 +62,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
: m_owner(owner)
, m_contentsDirty(false)
, m_maskLayer(0)
+ , m_ccLayerImpl(0)
, m_superlayer(0)
#ifndef NDEBUG
, m_debugID(s_nextLayerDebugID++)
@@ -77,7 +78,7 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner)
, m_opaque(true)
, m_geometryFlipped(false)
, m_needsDisplayOnBoundsChange(false)
- , m_ccLayerImpl(CCLayerImpl::create(this))
+ , m_doubleSided(true)
, m_replicaLayer(0)
{
}
@@ -94,7 +95,8 @@ LayerChromium::~LayerChromium()
void LayerChromium::cleanupResources()
{
- m_ccLayerImpl->cleanupResources();
+ if (m_ccLayerImpl)
+ m_ccLayerImpl->cleanupResources();
}
void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
@@ -105,8 +107,7 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
cleanupResources();
setNeedsDisplay();
}
-
- m_ccLayerImpl->setLayerRenderer(renderer);
+ m_layerRenderer = renderer;
}
void LayerChromium::setNeedsCommit()
@@ -188,7 +189,7 @@ void LayerChromium::setBounds(const IntSize& size)
bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height();
- m_ccLayerImpl->setBounds(size);
+ m_bounds = size;
if (firstResize)
setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height()));
@@ -240,7 +241,6 @@ LayerChromium* LayerChromium::superlayer() const
void LayerChromium::setName(const String& name)
{
m_name = name;
- m_ccLayerImpl->setName(name);
}
void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
@@ -288,6 +288,29 @@ void LayerChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
flattened[15] = m.m44();
}
+void LayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ layer->setAnchorPoint(m_anchorPoint);
+ layer->setAnchorPointZ(m_anchorPointZ);
+ layer->setBounds(m_bounds);
+ layer->setDebugBorderColor(m_debugBorderColor);
+ layer->setDebugBorderWidth(m_debugBorderWidth);
+ layer->setDoubleSided(m_doubleSided);
+ layer->setLayerRenderer(m_layerRenderer.get());
+ layer->setMasksToBounds(m_masksToBounds);
+ layer->setName(m_name);
+ layer->setOpacity(m_opacity);
+ layer->setPosition(m_position);
+ layer->setPreserves3D(preserves3D());
+ layer->setSublayerTransform(m_sublayerTransform);
+ layer->setTransform(m_transform);
+
+ if (maskLayer())
+ maskLayer()->pushPropertiesTo(layer->maskLayer());
+ if (replicaLayer())
+ replicaLayer()->pushPropertiesTo(layer->replicaLayer());
+}
+
GraphicsContext3D* LayerChromium::layerRendererContext() const
{
ASSERT(layerRenderer());
@@ -316,31 +339,6 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform
GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
}
-
-
-// Returns true if any of the layer's descendants has drawable content.
-bool LayerChromium::descendantsDrawContent()
-{
- const Vector<RefPtr<LayerChromium> >& sublayers = getSublayers();
- for (size_t i = 0; i < sublayers.size(); ++i)
- if (sublayers[i]->descendantsDrawContentRecursive())
- return true;
- return false;
-}
-
-// Returns true if either this layer or one of its descendants has drawable content.
-bool LayerChromium::descendantsDrawContentRecursive()
-{
- if (drawsContent())
- return true;
-
- const Vector<RefPtr<LayerChromium> >& sublayers = getSublayers();
- for (size_t i = 0; i < sublayers.size(); ++i)
- if (sublayers[i]->descendantsDrawContentRecursive())
- return true;
- return false;
-}
-
String LayerChromium::layerTreeAsText() const
{
TextStream ts;
@@ -359,7 +357,8 @@ 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_ccLayerImpl)
+ m_ccLayerImpl->dumpLayerProperties(ts, indent+2);
if (m_replicaLayer) {
writeIndent(ts, indent+2);
ts << "Replica:\n";
@@ -385,48 +384,38 @@ void LayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
}
-// Begin calls that forward to the CCLayerImpl.
-// ==============================================
-// These exists just for debugging (via drawDebugBorder()).
-void LayerChromium::setBorderColor(const Color& color)
+PassRefPtr<CCLayerImpl> LayerChromium::createCCLayerImpl()
{
- m_ccLayerImpl->setDebugBorderColor(color);
- setNeedsCommit();
+ return CCLayerImpl::create(this);
}
-Color LayerChromium::borderColor() const
+void LayerChromium::createCCLayerImplIfNeeded()
{
- return m_ccLayerImpl->debugBorderColor();
+ if (!m_ccLayerImpl)
+ m_ccLayerImpl = createCCLayerImpl();
}
-void LayerChromium::setBorderWidth(float width)
+CCLayerImpl* LayerChromium::ccLayerImpl()
{
- m_ccLayerImpl->setDebugBorderWidth(width);
- setNeedsCommit();
+ return m_ccLayerImpl.get();
}
-float LayerChromium::borderWidth() const
-{
- return m_ccLayerImpl->debugBorderWidth();
-}
-
-LayerRendererChromium* LayerChromium::layerRenderer() const
+void LayerChromium::setBorderColor(const Color& color)
{
- return m_ccLayerImpl->layerRenderer();
+ m_debugBorderColor = color;
+ setNeedsCommit();
}
-void LayerChromium::setDoubleSided(bool doubleSided)
+void LayerChromium::setBorderWidth(float width)
{
- m_ccLayerImpl->setDoubleSided(doubleSided);
+ m_debugBorderWidth = width;
setNeedsCommit();
}
-const IntSize& LayerChromium::bounds() const
+LayerRendererChromium* LayerChromium::layerRenderer() const
{
- return m_ccLayerImpl->bounds();
+ return m_layerRenderer.get();
}
-// ==============================================
-// 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 29a2165..428ce61 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -89,6 +89,9 @@ public:
void setBackgroundColor(const Color& color) { m_backgroundColor = color; setNeedsCommit(); }
Color backgroundColor() const { return m_backgroundColor; }
+ void setBounds(const IntSize&);
+ const IntSize& bounds() const { return m_bounds; }
+
void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); }
bool clearsContext() const { return m_clearsContext; }
@@ -133,6 +136,9 @@ public:
void setTransform(const TransformationMatrix& transform) { m_transform = transform; setNeedsCommit(); }
const TransformationMatrix& transform() const { return m_transform; }
+ bool doubleSided() const { return m_doubleSided; }
+ void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); }
+
// FIXME: This setting is currently ignored.
void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); }
bool geometryFlipped() const { return m_geometryFlipped; }
@@ -143,9 +149,6 @@ public:
// 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; }
@@ -153,14 +156,14 @@ public:
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() const { return false; }
- virtual void updateContentsIfDirty() { }
+ virtual void paintContentsIfDirty() { }
+ virtual void updateCompositorResources() { }
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; }
@@ -170,21 +173,19 @@ public:
String layerTreeAsText() const;
void setBorderWidth(float);
- float borderWidth() const;
// Everything from here down in the public section will move to CCLayerImpl.
-
- CCLayerImpl* ccLayerImpl() const { return m_ccLayerImpl.get(); }
+ CCLayerImpl* ccLayerImpl();
+ void createCCLayerImplIfNeeded();
static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
float width, float height, float opacity,
int matrixLocation, int alphaLocation);
+ virtual void pushPropertiesTo(CCLayerImpl*);
+
// 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;
@@ -217,6 +218,11 @@ protected:
static const unsigned s_positionAttribLocation;
static const unsigned s_texCoordAttribLocation;
+ // Constructs a CCLayerImpl of the correct runtime type for this LayerChromium type.
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
+ // For now, the LayerChromium directly owns its CCLayerImpl.
+ RefPtr<CCLayerImpl> m_ccLayerImpl;
private:
void setNeedsCommit();
@@ -233,19 +239,22 @@ private:
// This should only be called from removeFromSuperlayer.
void removeSublayer(LayerChromium*);
- bool descendantsDrawContentRecursive();
-
Vector<RefPtr<LayerChromium> > m_sublayers;
LayerChromium* m_superlayer;
+ RefPtr<LayerRendererChromium> m_layerRenderer;
+
#ifndef NDEBUG
int m_debugID;
#endif
// Layer properties.
+ IntSize m_bounds;
FloatPoint m_position;
FloatPoint m_anchorPoint;
Color m_backgroundColor;
+ Color m_debugBorderColor;
+ float m_debugBorderWidth;
float m_opacity;
float m_zPosition;
float m_anchorPointZ;
@@ -255,13 +264,12 @@ private:
bool m_opaque;
bool m_geometryFlipped;
bool m_needsDisplayOnBoundsChange;
+ bool m_doubleSided;
TransformationMatrix m_transform;
TransformationMatrix m_sublayerTransform;
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 e7b299f..fc15abd 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -36,6 +36,7 @@
#include "cc/CCLayerImpl.h"
#include "Canvas2DLayerChromium.h"
+#include "FloatQuad.h"
#include "GeometryBinding.h"
#include "GraphicsContext3D.h"
#include "LayerChromium.h"
@@ -43,6 +44,7 @@
#include "NotImplemented.h"
#include "TextStream.h"
#include "TextureManager.h"
+#include "TraceEvent.h"
#include "WebGLLayerChromium.h"
#include "cc/CCLayerImpl.h"
#if USE(SKIA)
@@ -91,21 +93,23 @@ bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImp
return a->drawDepth() < b->drawDepth();
}
-PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context)
+PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
{
if (!context)
return 0;
- RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context)));
+ RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context, contentPaint, scrollbarPaint)));
if (!layerRenderer->hardwareCompositing())
return 0;
return layerRenderer.release();
}
-LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context)
- : m_rootLayer(0)
- , m_scrollPosition(IntPoint(-1, -1))
+LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint)
+ : m_viewportScrollPosition(IntPoint(-1, -1))
+ , m_rootLayer(0)
+ , m_rootLayerContentPaint(contentPaint)
+ , m_rootLayerScrollbarPaint(scrollbarPaint)
, m_currentShader(0)
, m_currentRenderSurface(0)
, m_offscreenFramebufferId(0)
@@ -114,8 +118,8 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte
, m_defaultRenderSurface(0)
{
m_hardwareCompositing = initializeSharedObjects();
- m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
- ASSERT(m_rootLayerTiler);
+ m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
+ ASSERT(m_rootLayerContentTiler);
m_headsUpDisplay = CCHeadsUpDisplay::create(this);
}
@@ -146,129 +150,149 @@ void LayerRendererChromium::useShader(unsigned programId)
}
}
-IntRect LayerRendererChromium::verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+IntRect LayerRendererChromium::verticalScrollbarRect() const
{
- IntRect verticalScrollbar(IntPoint(contentRect.maxX(), contentRect.y()), IntSize(visibleRect.width() - contentRect.width(), visibleRect.height()));
+ IntRect verticalScrollbar(IntPoint(m_viewportContentRect.maxX(), m_viewportContentRect.y()), IntSize(m_viewportVisibleRect.width() - m_viewportContentRect.width(), m_viewportVisibleRect.height()));
return verticalScrollbar;
}
-IntRect LayerRendererChromium::horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect)
+IntRect LayerRendererChromium::horizontalScrollbarRect() const
{
- IntRect horizontalScrollbar(IntPoint(contentRect.x(), contentRect.maxY()), IntSize(visibleRect.width(), visibleRect.height() - contentRect.height()));
+ IntRect horizontalScrollbar(IntPoint(m_viewportContentRect.x(), m_viewportContentRect.maxY()), IntSize(m_viewportVisibleRect.width(), m_viewportVisibleRect.height() - m_viewportContentRect.height()));
return horizontalScrollbar;
}
-void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect)
+void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
{
- m_rootLayerTiler->invalidateRect(dirtyRect);
+ m_rootLayerContentTiler->invalidateRect(dirtyRect);
+
+ // Scrollbars never need to render beyond the fold, so clip to the viewport.
+ IntRect visibleDirtyRect = dirtyRect;
+ visibleDirtyRect.intersect(m_viewportVisibleRect);
+
if (m_horizontalScrollbarTiler) {
- IntRect scrollbar = horizontalScrollbarRect(visibleRect, contentRect);
- if (dirtyRect.intersects(scrollbar)) {
+ IntRect scrollbar = horizontalScrollbarRect();
+ if (visibleDirtyRect.intersects(scrollbar)) {
m_horizontalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_horizontalScrollbarTiler->invalidateRect(dirtyRect);
+ m_horizontalScrollbarTiler->invalidateRect(visibleDirtyRect);
}
}
if (m_verticalScrollbarTiler) {
- IntRect scrollbar = verticalScrollbarRect(visibleRect, contentRect);
- if (dirtyRect.intersects(scrollbar)) {
+ IntRect scrollbar = verticalScrollbarRect();
+ if (visibleDirtyRect.intersects(scrollbar)) {
m_verticalScrollbarTiler->setLayerPosition(scrollbar.location());
- m_verticalScrollbarTiler->invalidateRect(dirtyRect);
+ m_verticalScrollbarTiler->invalidateRect(visibleDirtyRect);
}
}
}
-void LayerRendererChromium::updateRootLayerContents(TilePaintInterface& tilePaint, const IntRect& visibleRect)
+void LayerRendererChromium::updateRootLayerContents()
{
- m_rootLayerTiler->update(tilePaint, visibleRect);
+ TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
+ m_rootLayerContentTiler->update(*m_rootLayerContentPaint, m_viewportVisibleRect);
}
-void LayerRendererChromium::updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect)
+void LayerRendererChromium::updateRootLayerScrollbars()
{
- if (visibleRect.width() > contentRect.width()) {
- IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect);
+ TRACE_EVENT("LayerRendererChromium::updateRootLayerScrollbars", this, 0);
+ if (m_viewportVisibleRect.width() > m_viewportContentRect.width()) {
+ IntRect verticalScrollbar = verticalScrollbarRect();
IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_verticalScrollbarTiler)
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->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
} else
m_verticalScrollbarTiler.clear();
- if (visibleRect.height() > contentRect.height()) {
- IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect);
+ if (m_viewportVisibleRect.height() > m_viewportContentRect.height()) {
+ IntRect horizontalScrollbar = horizontalScrollbarRect();
IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize));
if (!m_horizontalScrollbarTiler)
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->update(*m_rootLayerScrollbarPaint, m_viewportVisibleRect);
} else
m_horizontalScrollbarTiler.clear();
}
void LayerRendererChromium::drawRootLayer()
{
- m_rootLayerTiler->draw(m_visibleRect);
+ m_rootLayerContentTiler->draw(m_viewportVisibleRect);
if (m_verticalScrollbarTiler)
- m_verticalScrollbarTiler->draw(m_visibleRect);
+ m_verticalScrollbarTiler->draw(m_viewportVisibleRect);
if (m_horizontalScrollbarTiler)
- m_horizontalScrollbarTiler->draw(m_visibleRect);
+ m_horizontalScrollbarTiler->draw(m_viewportVisibleRect);
+}
+
+void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
+{
+ bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
+
+ m_viewportVisibleRect = visibleRect;
+ m_viewportContentRect = contentRect;
+ m_viewportScrollPosition = scrollPosition;
+
+ if (visibleRectChanged) {
+ // Reset the current render surface to force an update of the viewport and
+ // projection matrix next time useRenderSurface is called.
+ m_currentRenderSurface = 0;
+
+ m_rootLayerContentTiler->invalidateEntireLayer();
+ if (m_horizontalScrollbarTiler)
+ m_horizontalScrollbarTiler->invalidateEntireLayer();
+ if (m_verticalScrollbarTiler)
+ m_verticalScrollbarTiler->invalidateEntireLayer();
+ }
}
-void LayerRendererChromium::updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint)
+void LayerRendererChromium::updateAndDrawLayers()
{
ASSERT(m_hardwareCompositing);
if (!m_rootLayer)
return;
- updateRootLayerContents(tilePaint, visibleRect);
+ updateRootLayerContents();
+
// 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);
+ updateRootLayerScrollbars();
Vector<CCLayerImpl*> renderSurfaceLayerList;
- updateLayers(visibleRect, contentRect, scrollPosition, renderSurfaceLayerList);
+ updateLayers(renderSurfaceLayerList);
drawLayers(renderSurfaceLayerList);
+
+ if (isCompositingOffscreen())
+ copyOffscreenTextureToDisplay();
}
-void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- Vector<CCLayerImpl*>& renderSurfaceLayerList)
+void LayerRendererChromium::updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList)
{
+ TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
+ m_rootLayer->createCCLayerImplIfNeeded();
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.
-
- rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), visibleRect.size());
+ rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.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);
+ IntRect rootScissorRect(m_viewportContentRect);
// The scissorRect should not include the scroll offset.
- rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
+ rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
rootDrawLayer->setScissorRect(rootScissorRect);
m_defaultRenderSurface = rootDrawLayer->renderSurface();
@@ -283,16 +307,19 @@ void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRe
// concept of a large content layer.
updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
- updateContentsRecursive(m_rootLayer.get());
+ paintContentsRecursive(m_rootLayer.get());
+
+ updateCompositorResourcesRecursive(m_rootLayer.get());
}
void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList)
{
+ TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
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, m_visibleRect.width(), m_visibleRect.height()));
+ GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
// Bind the common vertex attributes used for drawing all the layers.
m_sharedGeometry->prepareForDraw();
@@ -363,11 +390,13 @@ void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurface
void LayerRendererChromium::finish()
{
+ TRACE_EVENT("LayerRendererChromium::finish", this, 0);
m_context->finish();
}
void LayerRendererChromium::present()
{
+ TRACE_EVENT("LayerRendererChromium::present", this, 0);
// We're done! Time to swapbuffers!
// Note that currently this has the same effect as swapBuffers; we should
@@ -382,7 +411,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
m_rootLayer = layer;
if (m_rootLayer)
m_rootLayer->setLayerRenderer(this);
- m_rootLayerTiler->invalidateEntireLayer();
+ m_rootLayerContentTiler->invalidateEntireLayer();
if (m_horizontalScrollbarTiler)
m_horizontalScrollbarTiler->invalidateEntireLayer();
if (m_verticalScrollbarTiler)
@@ -391,7 +420,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
{
- ASSERT(rect.maxX() <= visibleRectSize().width() && rect.maxY() <= visibleRectSize().height());
+ ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
if (!pixels)
return;
@@ -446,8 +475,29 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
// necessary transformations, scissor rectangles, render surfaces, etc.
void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList)
{
+ // Make sure we have CCLayerImpls for this subtree.
+ layer->createCCLayerImplIfNeeded();
layer->setLayerRenderer(this);
+ if (layer->maskLayer()) {
+ layer->maskLayer()->createCCLayerImplIfNeeded();
+ layer->maskLayer()->setLayerRenderer(this);
+ }
+ if (layer->replicaLayer()) {
+ layer->replicaLayer()->createCCLayerImplIfNeeded();
+ layer->replicaLayer()->setLayerRenderer(this);
+ }
+ if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) {
+ layer->replicaLayer()->maskLayer()->createCCLayerImplIfNeeded();
+ layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
+ }
+
CCLayerImpl* drawLayer = layer->ccLayerImpl();
+ // Currently we're calling pushPropertiesTo() twice - once here and once in updateCompositorResourcesRecursive().
+ // We should only call pushPropertiesTo() in commit, but because we rely on the draw layer state to update
+ // RenderSurfaces and we rely on RenderSurfaces being up to date in order to paint contents we have
+ // to update the draw layers twice.
+ // FIXME: Remove this call once layer updates no longer depend on render surfaces.
+ layer->pushPropertiesTo(drawLayer);
// 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
@@ -467,9 +517,9 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Where: P is the projection matrix
// M is the layer's matrix computed above
// S is the scale adjustment (to scale up to the layer size)
- IntSize bounds = layer->bounds();
- FloatPoint anchorPoint = layer->anchorPoint();
- FloatPoint position = layer->position();
+ IntSize bounds = drawLayer->bounds();
+ FloatPoint anchorPoint = drawLayer->anchorPoint();
+ FloatPoint position = drawLayer->position();
// Offset between anchor point and the center of the quad.
float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
@@ -477,16 +527,16 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
TransformationMatrix layerLocalTransform;
// LT = Tr[l]
- layerLocalTransform.translate3d(position.x(), position.y(), layer->anchorPointZ());
+ layerLocalTransform.translate3d(position.x(), position.y(), drawLayer->anchorPointZ());
// LT = Tr[l] * M[l]
- layerLocalTransform.multiply(layer->transform());
+ layerLocalTransform.multiply(drawLayer->transform());
// LT = Tr[l] * M[l] * Tr[c]
- layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
+ layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -drawLayer->anchorPointZ());
TransformationMatrix combinedTransform = parentMatrix;
combinedTransform = combinedTransform.multiply(layerLocalTransform);
- FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height());
+ FloatRect layerRect(-0.5 * drawLayer->bounds().width(), -0.5 * drawLayer->bounds().height(), drawLayer->bounds().width(), drawLayer->bounds().height());
IntRect transformedLayerRect;
// The layer and its descendants render on a new RenderSurface if any of
@@ -498,12 +548,11 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening
// out its children. The opacity value of the children layers is multiplied by the opacity
// of their parent.
- bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
- bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
- bool useSurfaceForMasking = layer->maskDrawLayer();
- bool useSurfaceForReflection = layer->replicaLayer();
- if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent())
- || useSurfaceForMasking || useSurfaceForReflection) {
+ bool useSurfaceForClipping = drawLayer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
+ bool useSurfaceForOpacity = drawLayer->opacity() != 1 && !drawLayer->preserves3D();
+ bool useSurfaceForMasking = drawLayer->maskLayer();
+ bool useSurfaceForReflection = drawLayer->replicaLayer();
+ if (useSurfaceForMasking || useSurfaceForReflection || ((useSurfaceForClipping || useSurfaceForOpacity) && drawLayer->descendantsDrawsContent())) {
RenderSurfaceChromium* renderSurface = drawLayer->renderSurface();
if (!renderSurface)
renderSurface = drawLayer->createRenderSurface();
@@ -516,15 +565,15 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
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() && layer->superlayer()->preserves3D())
+ renderSurface->m_drawOpacity = drawLayer->opacity();
+ if (drawLayer->superlayer() && drawLayer->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);
renderSurface->m_originTransform = layerOriginTransform;
- if (layerOriginTransform.isInvertible() && layer->superlayer()) {
+ if (layerOriginTransform.isInvertible() && drawLayer->superlayer()) {
TransformationMatrix parentToLayer = layerOriginTransform.inverse();
drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect()));
@@ -538,17 +587,14 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
renderSurface->m_layerList.clear();
- if (layer->maskDrawLayer()) {
- renderSurface->m_maskLayer = layer->maskDrawLayer();
- layer->maskDrawLayer()->setLayerRenderer(this);
- layer->maskDrawLayer()->setTargetRenderSurface(renderSurface);
+ if (drawLayer->maskLayer()) {
+ renderSurface->m_maskLayer = drawLayer->maskLayer();
+ drawLayer->maskLayer()->setTargetRenderSurface(renderSurface);
} else
renderSurface->m_maskLayer = 0;
- if (layer->replicaLayer() && layer->replicaLayer()->maskDrawLayer()) {
- layer->replicaLayer()->maskDrawLayer()->setLayerRenderer(this);
- layer->replicaLayer()->maskDrawLayer()->setTargetRenderSurface(renderSurface);
- }
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer())
+ drawLayer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface);
renderSurfaceLayerList.append(drawLayer);
} else {
@@ -556,10 +602,10 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
drawLayer->setDrawTransform(combinedTransform);
transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect));
- drawLayer->setDrawOpacity(layer->opacity());
+ drawLayer->setDrawOpacity(drawLayer->opacity());
- if (layer->superlayer()) {
- if (layer->superlayer()->preserves3D())
+ if (drawLayer->superlayer()) {
+ if (drawLayer->superlayer()->preserves3D())
drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity());
// Layers inherit the scissor rect from their superlayer.
@@ -571,7 +617,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
if (layer != m_rootLayer)
drawLayer->clearRenderSurface();
- if (layer->masksToBounds()) {
+ if (drawLayer->masksToBounds()) {
IntRect scissor = drawLayer->scissorRect();
scissor.intersect(transformedLayerRect);
drawLayer->setScissorRect(scissor);
@@ -581,7 +627,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
if (drawLayer->renderSurface())
drawLayer->setTargetRenderSurface(drawLayer->renderSurface());
else {
- ASSERT(layer->superlayer());
+ ASSERT(drawLayer->superlayer());
drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface());
}
@@ -595,7 +641,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
TransformationMatrix sublayerMatrix = drawLayer->drawTransform();
// Flatten to 2D if the layer doesn't preserve 3D.
- if (!layer->preserves3D()) {
+ if (!drawLayer->preserves3D()) {
sublayerMatrix.setM13(0);
sublayerMatrix.setM23(0);
sublayerMatrix.setM31(0);
@@ -606,7 +652,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
}
// Apply the sublayer transform at the center of the layer.
- sublayerMatrix.multiply(layer->sublayerTransform());
+ sublayerMatrix.multiply(drawLayer->sublayerTransform());
// The origin of the sublayers is the top left corner of the layer, not the
// center. The matrix passed down to the sublayers is therefore:
@@ -619,6 +665,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); ++i) {
+ sublayers[i]->createCCLayerImplIfNeeded();
CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl();
updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants);
@@ -635,7 +682,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
}
}
- if (layer->masksToBounds() || useSurfaceForMasking) {
+ if (drawLayer->masksToBounds() || useSurfaceForMasking) {
IntRect drawableContentRect = drawLayer->drawableContentRect();
drawableContentRect.intersect(transformedLayerRect);
drawLayer->setDrawableContentRect(drawableContentRect);
@@ -651,7 +698,7 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Don't clip if the layer is reflected as the reflection shouldn't be
// clipped.
- if (!layer->replicaLayer()) {
+ if (!drawLayer->replicaLayer()) {
renderSurface->m_contentRect.intersect(drawLayer->scissorRect());
FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter();
centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
@@ -675,10 +722,10 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Compute the transformation matrix used to draw the replica of the render
// surface.
- if (layer->replicaLayer()) {
+ if (drawLayer->replicaLayer()) {
renderSurface->m_replicaDrawTransform = renderSurface->m_originTransform;
- renderSurface->m_replicaDrawTransform.translate3d(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y(), 0);
- renderSurface->m_replicaDrawTransform.multiply(layer->replicaLayer()->transform());
+ renderSurface->m_replicaDrawTransform.translate3d(drawLayer->replicaLayer()->position().x(), drawLayer->replicaLayer()->position().y(), 0);
+ renderSurface->m_replicaDrawTransform.multiply(drawLayer->replicaLayer()->transform());
renderSurface->m_replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0);
}
}
@@ -686,8 +733,8 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// Compute the depth value of the center of the layer which will be used when
// sorting the layers for the preserves-3d property.
const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform();
- if (layer->superlayer()) {
- if (!layer->superlayer()->preserves3D())
+ if (drawLayer->superlayer()) {
+ if (!drawLayer->superlayer()->preserves3D())
drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth());
else
drawLayer->setDrawDepth(layerDrawMatrix.m43());
@@ -697,24 +744,50 @@ void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* lay
// 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
// skip the sorting as the superlayer will sort all the descendants anyway.
- if (layer->preserves3D() && (!layer->superlayer() || !layer->superlayer()->preserves3D()))
+ if (drawLayer->preserves3D() && (!drawLayer->superlayer() || !drawLayer->superlayer()->preserves3D()))
std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ);
}
-void LayerRendererChromium::updateContentsRecursive(LayerChromium* layer)
+void LayerRendererChromium::paintContentsRecursive(LayerChromium* layer)
{
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); ++i)
- updateContentsRecursive(sublayers[i].get());
+ paintContentsRecursive(sublayers[i].get());
+
+ if (layer->bounds().isEmpty())
+ return;
if (layer->drawsContent())
- layer->updateContentsIfDirty();
+ layer->paintContentsIfDirty();
if (layer->maskLayer() && layer->maskLayer()->drawsContent())
- layer->maskLayer()->updateContentsIfDirty();
+ layer->maskLayer()->paintContentsIfDirty();
if (layer->replicaLayer() && layer->replicaLayer()->drawsContent())
- layer->replicaLayer()->updateContentsIfDirty();
+ layer->replicaLayer()->paintContentsIfDirty();
if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent())
- layer->replicaLayer()->maskLayer()->updateContentsIfDirty();
+ layer->replicaLayer()->maskLayer()->paintContentsIfDirty();
+}
+
+void LayerRendererChromium::updateCompositorResourcesRecursive(LayerChromium* layer)
+{
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); ++i)
+ updateCompositorResourcesRecursive(sublayers[i].get());
+
+ if (layer->bounds().isEmpty())
+ return;
+
+ CCLayerImpl* drawLayer = layer->ccLayerImpl();
+
+ if (drawLayer->drawsContent())
+ drawLayer->updateCompositorResources();
+ if (drawLayer->maskLayer() && drawLayer->maskLayer()->drawsContent())
+ drawLayer->maskLayer()->updateCompositorResources();
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->drawsContent())
+ drawLayer->replicaLayer()->updateCompositorResources();
+ if (drawLayer->replicaLayer() && drawLayer->replicaLayer()->maskLayer() && drawLayer->replicaLayer()->maskLayer()->drawsContent())
+ drawLayer->replicaLayer()->maskLayer()->updateCompositorResources();
+
+ layer->pushPropertiesTo(drawLayer);
}
void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen)
@@ -788,22 +861,38 @@ void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium*
return;
}
- if (layer->bounds().isEmpty())
+ if (layer->bounds().isEmpty()) {
+ layer->unreserveContentsTexture();
return;
+ }
setScissorToRect(layer->scissorRect());
// Check if the layer falls within the visible bounds of the page.
IntRect layerRect = layer->getDrawRect();
bool isLayerVisible = layer->scissorRect().intersects(layerRect);
- if (!isLayerVisible)
+ if (!isLayerVisible) {
+ layer->unreserveContentsTexture();
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->renderSurface() ? layer->renderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
- if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0)
- return;
+ TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
+
+ if (!layer->doubleSided()) {
+ FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
+ FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect));
+ FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
+ FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
+ FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
+ FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
+ FloatPoint3D zAxis = xAxis.cross(yAxis);
+ if (zAxis.z() < 0) {
+ layer->unreserveContentsTexture();
+ return;
+ }
+ }
if (layer->drawsContent())
layer->draw();
@@ -880,10 +969,10 @@ bool LayerRendererChromium::initializeSharedObjects()
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_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
+ m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
+ m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
+ m_pluginLayerProgram = adoptPtr(new CCPluginLayerImpl::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()));
@@ -920,7 +1009,7 @@ void LayerRendererChromium::cleanupSharedObjects()
GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
// Clear tilers before the texture manager, as they have references to textures.
- m_rootLayerTiler.clear();
+ m_rootLayerContentTiler.clear();
m_horizontalScrollbarTiler.clear();
m_verticalScrollbarTiler.clear();
diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 7e8850a..667ede2 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -34,16 +34,17 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "CanvasLayerChromium.h"
#include "ContentLayerChromium.h"
#include "IntRect.h"
#include "LayerChromium.h"
#include "LayerTilerChromium.h"
-#include "PluginLayerChromium.h"
#include "RenderSurfaceChromium.h"
#include "SkBitmap.h"
#include "VideoLayerChromium.h"
+#include "cc/CCCanvasLayerImpl.h"
#include "cc/CCHeadsUpDisplay.h"
+#include "cc/CCPluginLayerImpl.h"
+#include "cc/CCVideoLayerImpl.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
@@ -66,17 +67,18 @@ class CCHeadsUpDisplay;
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
public:
- static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D> graphicsContext3D);
+ static PassRefPtr<LayerRendererChromium> create(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
~LayerRendererChromium();
GraphicsContext3D* context();
- void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect);
+ void invalidateRootLayerRect(const IntRect& dirtyRect);
+
+ void setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition);
// updates and draws the current layers onto the backbuffer
- void updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition,
- TilePaintInterface&, TilePaintInterface& scrollbarPaint);
+ void updateAndDrawLayers();
// waits for rendering to finish
void finish();
@@ -84,7 +86,7 @@ public:
// puts backbuffer onscreen
void present();
- IntSize visibleRectSize() const { return m_visibleRect.size(); }
+ IntSize viewportSize() const { return m_viewportVisibleRect.size(); }
void setRootLayer(PassRefPtr<LayerChromium> layer);
LayerChromium* rootLayer() { return m_rootLayer.get(); }
@@ -94,8 +96,6 @@ public:
void setCompositeOffscreen(bool);
bool isCompositingOffscreen() const { return m_compositeOffscreen; }
- LayerTexture* getOffscreenLayerTexture();
- void copyOffscreenTextureToDisplay();
unsigned createLayerTexture();
void deleteLayerTexture(unsigned);
@@ -111,13 +111,13 @@ public:
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(); }
+ const CCCanvasLayerImpl::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); }
+ const CCPluginLayerImpl::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); }
+ const CCVideoLayerImpl::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); }
+ const CCVideoLayerImpl::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); }
void resizeOnscreenContent(const IntSize&);
@@ -132,19 +132,21 @@ public:
String layerTreeAsText() const;
private:
- explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D);
+ explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D>, PassOwnPtr<TilePaintInterface> contentPaint, PassOwnPtr<TilePaintInterface> scrollbarPaint);
- 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 updateLayers(Vector<CCLayerImpl*>& renderSurfaceLayerList);
+ void updateRootLayerContents();
+ void updateRootLayerScrollbars();
void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList);
- void updateContentsRecursive(LayerChromium*);
+ void paintContentsRecursive(LayerChromium*);
+ void updateCompositorResourcesRecursive(LayerChromium*);
void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList);
void drawLayer(CCLayerImpl*, RenderSurfaceChromium*);
void drawRootLayer();
+ LayerTexture* getOffscreenLayerTexture();
+ void copyOffscreenTextureToDisplay();
bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
@@ -161,19 +163,22 @@ private:
bool initializeSharedObjects();
void cleanupSharedObjects();
- static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
- static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect);
+ IntRect verticalScrollbarRect() const;
+ IntRect horizontalScrollbarRect() const;
- IntRect m_visibleRect;
+ IntRect m_viewportVisibleRect;
+ IntRect m_viewportContentRect;
+ IntPoint m_viewportScrollPosition;
TransformationMatrix m_projectionMatrix;
RefPtr<LayerChromium> m_rootLayer;
- OwnPtr<LayerTilerChromium> m_rootLayerTiler;
+ OwnPtr<TilePaintInterface> m_rootLayerContentPaint;
+ OwnPtr<TilePaintInterface> m_rootLayerScrollbarPaint;
+ OwnPtr<LayerTilerChromium> m_rootLayerContentTiler;
OwnPtr<LayerTilerChromium> m_horizontalScrollbarTiler;
OwnPtr<LayerTilerChromium> m_verticalScrollbarTiler;
- IntPoint m_scrollPosition;
bool m_hardwareCompositing;
unsigned m_currentShader;
@@ -202,13 +207,13 @@ private:
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<CCCanvasLayerImpl::Program> m_canvasLayerProgram;
+ OwnPtr<CCVideoLayerImpl::RGBAProgram> m_videoLayerRGBAProgram;
+ OwnPtr<CCVideoLayerImpl::YUVProgram> m_videoLayerYUVProgram;
+ OwnPtr<CCPluginLayerImpl::Program> m_pluginLayerProgram;
OwnPtr<TextureManager> m_textureManager;
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
index 86592a6..bc37201 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp
@@ -34,6 +34,7 @@
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
+#include "TraceEvent.h"
#include <wtf/PassOwnArrayPtr.h>
@@ -84,58 +85,50 @@ void LayerTilerChromium::reset()
{
m_tiles.clear();
m_unusedTiles.clear();
-
m_tilingData.setTotalSize(0, 0);
- m_lastUpdateLayerRect = IntRect();
}
LayerTilerChromium::Tile* LayerTilerChromium::createTile(int i, int j)
{
- const int index = tileIndex(i, j);
- ASSERT(!m_tiles[index]);
+ ASSERT(!tileAt(i, j));
+ RefPtr<Tile> tile;
if (m_unusedTiles.size() > 0) {
- m_tiles[index] = m_unusedTiles.last().release();
+ tile = m_unusedTiles.last().release();
m_unusedTiles.removeLast();
+ ASSERT(tile->refCount() == 1);
} else {
GraphicsContext3D* context = layerRendererContext();
TextureManager* manager = layerRenderer()->textureManager();
- OwnPtr<Tile> tile = adoptPtr(new Tile(LayerTexture::create(context, manager)));
- m_tiles[index] = tile.release();
+ tile = adoptRef(new Tile(LayerTexture::create(context, manager)));
}
+ m_tiles.add(make_pair(i, j), tile);
+
+ tile->moveTo(i, j);
+ tile->m_dirtyLayerRect = tileLayerRect(tile.get());
- m_tiles[index]->m_dirtyLayerRect = tileLayerRect(i, j);
- return m_tiles[index].get();
+ return tile.get();
}
-void LayerTilerChromium::invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect)
+void LayerTilerChromium::invalidateTiles(const IntRect& contentRect)
{
if (!m_tiles.size())
return;
- IntRect oldContentRect = layerRectToContentRect(oldLayerRect);
- int oldLeft, oldTop, oldRight, oldBottom;
- contentRectToTileIndices(oldContentRect, oldLeft, oldTop, oldRight, oldBottom);
-
- IntRect newContentRect = layerRectToContentRect(newLayerRect);
- int newLeft, newTop, newRight, newBottom;
- contentRectToTileIndices(newContentRect, newLeft, newTop, newRight, newBottom);
-
- // Iterating through just the old tile indices is an optimization to avoid
- // iterating through the entire m_tiles array.
- for (int j = oldTop; j <= oldBottom; ++j) {
- for (int i = oldLeft; i <= oldRight; ++i) {
- if (i >= newLeft && i <= newRight && j >= newTop && j <= newBottom)
- continue;
-
- const int index = tileIndex(i, j);
- if (m_tiles[index])
- m_unusedTiles.append(m_tiles[index].release());
- }
+ Vector<TileMapKey> removeKeys;
+ for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) {
+ Tile* tile = iter->second.get();
+ IntRect tileRect = tileContentRect(tile);
+ if (tileRect.intersects(contentRect))
+ continue;
+ removeKeys.append(iter->first);
}
+
+ for (size_t i = 0; i < removeKeys.size(); ++i)
+ m_unusedTiles.append(m_tiles.take(removeKeys[i]));
}
-void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const
+void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, int& left, int& top, int& right, int& bottom) const
{
const IntRect layerRect = contentRectToLayerRect(contentRect);
@@ -163,36 +156,28 @@ IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) con
return contentRect;
}
-int LayerTilerChromium::tileIndex(int i, int j) const
+LayerTilerChromium::Tile* LayerTilerChromium::tileAt(int i, int j) const
{
- return m_tilingData.tileIndex(i, j);
+ Tile* tile = m_tiles.get(make_pair(i, j)).get();
+ ASSERT(!tile || tile->refCount() == 1);
+ return tile;
}
-IntRect LayerTilerChromium::tileContentRect(int i, int j) const
+IntRect LayerTilerChromium::tileContentRect(const Tile* tile) const
{
- IntRect contentRect = tileLayerRect(i, j);
+ IntRect contentRect = tileLayerRect(tile);
contentRect.move(m_layerPosition.x(), m_layerPosition.y());
return contentRect;
}
-IntRect LayerTilerChromium::tileLayerRect(int i, int j) const
+IntRect LayerTilerChromium::tileLayerRect(const Tile* tile) const
{
- const int index = m_tilingData.tileIndex(i, j);
+ const int index = m_tilingData.tileIndex(tile->i(), tile->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)
{
if (contentRect.isEmpty())
@@ -202,16 +187,16 @@ void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
// Dirty rects are always in layer space, as the layer could be repositioned
// after invalidation.
- IntRect layerRect = contentRectToLayerRect(contentRect);
+ const IntRect layerRect = contentRectToLayerRect(contentRect);
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();
+ Tile* tile = tileAt(i, j);
if (!tile)
continue;
- IntRect bound = tileLayerRect(i, j);
+ IntRect bound = tileLayerRect(tile);
bound.intersect(layerRect);
tile->m_dirtyLayerRect.unite(bound);
}
@@ -220,14 +205,13 @@ void LayerTilerChromium::invalidateRect(const IntRect& contentRect)
void LayerTilerChromium::invalidateEntireLayer()
{
- for (size_t i = 0; i < m_tiles.size(); ++i) {
- if (m_tiles[i])
- m_unusedTiles.append(m_tiles[i].release());
+ for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) {
+ ASSERT(iter->second->refCount() == 1);
+ m_unusedTiles.append(iter->second.release());
}
m_tiles.clear();
m_tilingData.setTotalSize(0, 0);
- m_lastUpdateLayerRect = IntRect();
}
void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& contentRect)
@@ -237,10 +221,7 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
// Invalidate old tiles that were previously used but aren't in use this
// frame so that they can get reused for new tiles.
- IntRect layerRect = contentRectToLayerRect(contentRect);
- invalidateTiles(m_lastUpdateLayerRect, layerRect);
- m_lastUpdateLayerRect = layerRect;
-
+ invalidateTiles(contentRect);
growLayerToContain(contentRect);
// Create tiles as needed, expanding a dirty rect to contain all
@@ -250,11 +231,11 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
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();
+ Tile* tile = tileAt(i, j);
if (!tile)
tile = createTile(i, j);
if (!tile->texture()->isValid(m_tileSize, GraphicsContext3D::RGBA))
- tile->m_dirtyLayerRect = tileLayerRect(i, j);
+ tile->m_dirtyLayerRect = tileLayerRect(tile);
dirtyLayerRect.unite(tile->m_dirtyLayerRect);
}
}
@@ -267,10 +248,16 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont
m_canvas.resize(paintRect.size());
PlatformCanvas::Painter canvasPainter(&m_canvas);
canvasPainter.context()->translate(-paintRect.x(), -paintRect.y());
- painter.paint(*canvasPainter.context(), paintRect);
+ {
+ TRACE_EVENT("LayerTilerChromium::update::paint", this, 0);
+ painter.paint(*canvasPainter.context(), paintRect);
+ }
PlatformCanvas::AutoLocker locker(&m_canvas);
- updateFromPixels(paintRect, locker.pixels());
+ {
+ TRACE_EVENT("LayerTilerChromium::updateFromPixels", this, 0);
+ updateFromPixels(paintRect, locker.pixels());
+ }
}
void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels)
@@ -285,14 +272,14 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_
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();
+ Tile* tile = tileAt(i, j);
if (!tile)
CRASH();
if (!tile->dirty())
continue;
// Calculate page-space rectangle to copy from.
- IntRect sourceRect = tileContentRect(i, j);
+ IntRect sourceRect = tileContentRect(tile);
const IntPoint anchor = sourceRect.location();
sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect));
if (sourceRect.isEmpty())
@@ -366,8 +353,7 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
contentRectToTileIndices(contentRect, left, top, right, bottom);
for (int j = top; j <= bottom; ++j) {
for (int i = left; i <= right; ++i) {
- const int index = tileIndex(i, j);
- Tile* tile = m_tiles[index].get();
+ Tile* tile = tileAt(i, j);
ASSERT(tile);
tile->texture()->bindTexture();
@@ -376,11 +362,11 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
// 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);
+ IntRect tileRect = m_tilingData.tileBounds(m_tilingData.tileIndex(tile->i(), tile->j()));
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);
- IntPoint texOffset = m_tilingData.textureOffset(i, j);
+ IntPoint texOffset = m_tilingData.textureOffset(tile->i(), tile->j());
float tileWidth = static_cast<float>(m_tileSize.width());
float tileHeight = static_cast<float>(m_tileSize.height());
float texTranslateX = texOffset.x() / tileWidth;
@@ -395,37 +381,15 @@ void LayerTilerChromium::draw(const IntRect& contentRect)
}
}
-void LayerTilerChromium::resizeLayer(const IntSize& size)
-{
- if (layerSize() == size)
- return;
-
- const IntSize oldTileSize = layerTileSize();
- m_tilingData.setTotalSize(size.width(), size.height());
- const IntSize newTileSize = layerTileSize();
-
- if (oldTileSize == newTileSize)
- return;
-
- if (newTileSize.height() && (newTileSize.width() > INT_MAX / newTileSize.height()))
- CRASH();
-
- Vector<OwnPtr<Tile> > newTiles;
- 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);
-}
-
void LayerTilerChromium::growLayerToContain(const IntRect& contentRect)
{
// Grow the tile array to contain this content rect.
IntRect layerRect = contentRectToLayerRect(contentRect);
IntSize rectSize = IntSize(layerRect.maxX(), layerRect.maxY());
- IntSize newSize = rectSize.expandedTo(layerSize());
- resizeLayer(newSize);
+ IntSize oldLayerSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY());
+ IntSize newSize = rectSize.expandedTo(oldLayerSize);
+ m_tilingData.setTotalSize(newSize.width(), newSize.height());
}
void LayerTilerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
index bdb35a5..2f356e4 100644
--- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h
@@ -33,7 +33,9 @@
#include "LayerTexture.h"
#include "PlatformCanvas.h"
#include "TilingData.h"
+#include <wtf/HashTraits.h>
#include <wtf/OwnArrayPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
@@ -70,20 +72,26 @@ public:
private:
LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption);
- class Tile {
+ class Tile : public RefCounted<Tile> {
WTF_MAKE_NONCOPYABLE(Tile);
public:
- explicit Tile(PassOwnPtr<LayerTexture> tex) : m_tex(tex) {}
+ explicit Tile(PassOwnPtr<LayerTexture> tex) : m_tex(tex), m_i(-1), m_j(-1) {}
LayerTexture* texture() { return m_tex.get(); }
bool dirty() const { return !m_dirtyLayerRect.isEmpty(); }
void clearDirty() { m_dirtyLayerRect = IntRect(); }
+ int i() const { return m_i; }
+ int j() const { return m_j; }
+ void moveTo(int i, int j) { m_i = i; m_j = j; }
+
// Layer-space dirty rectangle that needs to be repainted.
IntRect m_dirtyLayerRect;
private:
OwnPtr<LayerTexture> m_tex;
+ int m_i;
+ int m_j;
};
void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix,
@@ -92,40 +100,45 @@ private:
float texScaleX, float texScaleY,
const LayerTilerChromium::Program*);
- void resizeLayer(const IntSize& size);
// Grow layer size to contain this rectangle.
void growLayerToContain(const IntRect& contentRect);
LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
GraphicsContext3D* layerRendererContext() const;
Tile* createTile(int i, int j);
- // Invalidate any tiles which do not intersect with the newLayerRect.
- void invalidateTiles(const IntRect& oldLayerRect, const IntRect& newLayerRect);
+ // Invalidate any tiles which do not intersect with the contentRect
+ void invalidateTiles(const IntRect& contentRect);
void reset();
void contentRectToTileIndices(const IntRect& contentRect, int &left, int &top, int &right, int &bottom) const;
IntRect contentRectToLayerRect(const IntRect& contentRect) const;
IntRect layerRectToContentRect(const IntRect& layerRect) const;
- // Returns the index into m_tiles for a given tile location.
- int tileIndex(int i, int j) const;
- // Returns the bounds in content space for a given tile location.
- IntRect tileContentRect(int i, int j) const;
- // Returns the bounds in layer space for a given tile location.
- IntRect tileLayerRect(int i, int j) const;
-
- IntSize layerSize() const;
- IntSize layerTileSize() const;
+ Tile* tileAt(int, int) const;
+ IntRect tileContentRect(const Tile*) const;
+ IntRect tileLayerRect(const Tile*) const;
IntSize m_tileSize;
- IntRect m_lastUpdateLayerRect;
IntPoint m_layerPosition;
bool m_skipsDraw;
- // Logical 2D array of tiles (dimensions of m_layerTileSize)
- Vector<OwnPtr<Tile> > m_tiles;
- // Linear array of unused tiles.
- Vector<OwnPtr<Tile> > m_unusedTiles;
+ // Default hash key traits for integers disallow 0 and -1 as a key, so
+ // use a custom hash trait which disallows -1 and -2 instead.
+ typedef std::pair<int, int> TileMapKey;
+ struct TileMapKeyTraits : HashTraits<TileMapKey> {
+ static const bool emptyValueIsZero = false;
+ static const bool needsDestruction = false;
+ static TileMapKey emptyValue() { return std::make_pair(-1, -1); }
+ static void constructDeletedValue(TileMapKey& slot) { slot = std::make_pair(-2, -2); }
+ static bool isDeletedValue(TileMapKey value) { return value.first == -2 && value.second == -2; }
+ };
+ // FIXME: The mapped value in TileMap should really be an OwnPtr, as the
+ // refcount of a Tile should never be more than 1. However, HashMap
+ // doesn't easily support OwnPtr as a value.
+ typedef HashMap<TileMapKey, RefPtr<Tile>, DefaultHash<TileMapKey>::Hash, TileMapKeyTraits> TileMap;
+ TileMap m_tiles;
+ // Tightly packed set of unused tiles.
+ Vector<RefPtr<Tile> > m_unusedTiles;
PlatformCanvas m_canvas;
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
index 5d595ad..3667fbb 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp
@@ -29,10 +29,10 @@
#include "PluginLayerChromium.h"
-#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
-#include <GLES2/gl2.h>
+#include "cc/CCLayerImpl.h"
+#include "cc/CCPluginLayerImpl.h"
namespace WebCore {
@@ -43,40 +43,26 @@ PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromiu
PluginLayerChromium::PluginLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
+ , m_textureId(0)
{
}
-void PluginLayerChromium::setTextureId(unsigned id)
+PassRefPtr<CCLayerImpl> PluginLayerChromium::createCCLayerImpl()
{
- m_textureId = id;
+ return CCPluginLayerImpl::create(this);
}
-void PluginLayerChromium::updateContentsIfDirty()
+void PluginLayerChromium::setTextureId(unsigned id)
{
+ m_textureId = id;
}
-void PluginLayerChromium::draw()
+void PluginLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
{
- ASSERT(layerRenderer());
- 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));
-
- // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
- // where it will only happen once per texture.
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- 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(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());
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCPluginLayerImpl* pluginLayer = static_cast<CCPluginLayerImpl*>(layer);
+ pluginLayer->setTextureId(m_textureId);
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
index 8d66f5f..852dc2e 100644
--- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h
@@ -38,18 +38,19 @@ class PluginLayerChromium : public LayerChromium {
public:
static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual bool drawsContent() const { return true; }
- virtual void updateContentsIfDirty();
- virtual void draw();
-
+
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
void setTextureId(unsigned textureId);
-
- typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+ unsigned textureId() const { return m_textureId; }
+
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
virtual const char* layerTypeAsString() const { return "PluginLayer"; }
private:
- PluginLayerChromium(GraphicsLayerChromium* owner);
+ explicit PluginLayerChromium(GraphicsLayerChromium* owner);
unsigned m_textureId;
};
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
index 49b3462..b7f447b 100644
--- a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
@@ -248,7 +248,7 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo()
, m_vTextureLocation(-1)
, m_alphaLocation(-1)
, m_ccMatrixLocation(-1)
- , m_signAdjLocation(-1)
+ , m_yuvAdjLocation(-1)
{
}
@@ -259,10 +259,10 @@ bool FragmentShaderYUVVideo::init(GraphicsContext3D* context, unsigned program)
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");
+ m_yuvAdjLocation = context->getUniformLocation(program, "yuv_adj");
return m_yTextureLocation != -1 && m_uTextureLocation != -1 && m_vTextureLocation != -1
- && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_signAdjLocation != -1;
+ && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_yuvAdjLocation != -1;
}
String FragmentShaderYUVVideo::getShaderString() const
@@ -276,14 +276,15 @@ String FragmentShaderYUVVideo::getShaderString() const
uniform sampler2D u_texture;
uniform sampler2D v_texture;
uniform float alpha;
- uniform float adj;
+ uniform vec3 yuv_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);
+ float y_raw = texture2D(y_texture, y_texCoord).x;
+ float u_unsigned = texture2D(u_texture, uv_texCoord).x;
+ float v_unsigned = texture2D(v_texture, uv_texCoord).x;
+ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
+ vec3 rgb = cc_matrix * yuv;
gl_FragColor = vec4(rgb, float(1)) * alpha;
}
);
diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
index 758c62b..3a3e175 100644
--- a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h
@@ -158,7 +158,7 @@ public:
int vTextureLocation() const { return m_vTextureLocation; }
int alphaLocation() const { return m_alphaLocation; }
int ccMatrixLocation() const { return m_ccMatrixLocation; }
- int signAdjLocation() const { return m_signAdjLocation; }
+ int yuvAdjLocation() const { return m_yuvAdjLocation; }
private:
int m_yTextureLocation;
@@ -166,7 +166,7 @@ private:
int m_vTextureLocation;
int m_alphaLocation;
int m_ccMatrixLocation;
- int m_signAdjLocation;
+ int m_yuvAdjLocation;
};
class FragmentShaderColor {
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index 9423d1e..7cd47fe 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -113,13 +113,13 @@ void SimpleFontData::platformInit()
m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
- if (m_orientation == Vertical) {
+ if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
- if ((vheaSize <= 0) && (vorgSize <= 0))
- m_orientation = Horizontal;
+ if ((vheaSize > 0) || (vorgSize > 0))
+ m_hasVerticalGlyphs = true;
}
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 5d7a6e7..182e730 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -33,7 +33,6 @@
#if USE(ACCELERATED_COMPOSITING)
#include "VideoLayerChromium.h"
-#include "cc/CCLayerImpl.h"
#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
@@ -41,17 +40,11 @@
#include "RenderLayerBacking.h"
#include "VideoFrameChromium.h"
#include "VideoFrameProvider.h"
+#include "cc/CCLayerImpl.h"
+#include "cc/CCVideoLayerImpl.h"
namespace WebCore {
-// These values are magic numbers that are used in the transformation
-// from YUV to RGB color values.
-const float VideoLayerChromium::yuv2RGB[9] = {
- 1.f, 1.f, 1.f,
- 0.f, -.344f, 1.772f,
- 1.403f, -.714f, 0.f,
-};
-
PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
VideoFrameProvider* provider)
{
@@ -71,23 +64,37 @@ VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameP
VideoLayerChromium::~VideoLayerChromium()
{
cleanupResources();
+ deleteTexturesInUse();
}
-void VideoLayerChromium::cleanupResources()
+PassRefPtr<CCLayerImpl> VideoLayerChromium::createCCLayerImpl()
+{
+ return CCVideoLayerImpl::create(this);
+}
+
+void VideoLayerChromium::deleteTexturesInUse()
{
- LayerChromium::cleanupResources();
- releaseCurrentFrame();
if (!layerRenderer())
return;
GraphicsContext3D* context = layerRendererContext();
for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
- if (m_textures[plane])
- GLC(context, context->deleteTexture(m_textures[plane]));
+ Texture texture = m_textures[plane];
+ if (!texture.isEmpty && texture.ownedByLayerRenderer)
+ GLC(context, context->deleteTexture(texture.id));
}
}
-void VideoLayerChromium::updateContentsIfDirty()
+void VideoLayerChromium::cleanupResources()
+{
+ LayerChromium::cleanupResources();
+ if (m_currentFrame)
+ releaseCurrentFrame();
+ else
+ resetFrameParameters();
+}
+
+void VideoLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty)
return;
@@ -116,6 +123,9 @@ void VideoLayerChromium::updateContentsIfDirty()
return;
}
+ // If the incoming frame is backed by a texture (i.e. decoded in hardware),
+ // then we do not need to allocate a texture via the layer renderer. Instead
+ // we save the texture data then exit.
if (frame->surfaceType() == VideoFrameChromium::TypeTexture) {
releaseCurrentFrame();
saveCurrentFrame(frame);
@@ -136,8 +146,9 @@ void VideoLayerChromium::updateContentsIfDirty()
// Update texture planes.
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- ASSERT(frame->requiredTextureSize(plane) == m_textureSizes[plane]);
- updateTexture(context, m_textures[plane], frame->requiredTextureSize(plane), textureFormat, frame->data(plane));
+ Texture texture = m_textures[plane];
+ ASSERT(frame->requiredTextureSize(plane) == texture.size);
+ updateTexture(context, texture.id, texture.size, textureFormat, frame->data(plane));
}
m_dirtyRect.setSize(FloatSize());
@@ -146,7 +157,19 @@ void VideoLayerChromium::updateContentsIfDirty()
m_provider->putCurrentFrame(frame);
}
-unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
+void VideoLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+ LayerChromium::pushPropertiesTo(layer);
+
+ CCVideoLayerImpl* videoLayer = static_cast<CCVideoLayerImpl*>(layer);
+ videoLayer->setSkipsDraw(m_skipsDraw);
+ videoLayer->setFrameFormat(m_frameFormat);
+ for (size_t i = 0; i < 3; ++i)
+ videoLayer->setTexture(i, m_textures[i]);
+}
+
+
+unsigned VideoLayerChromium::determineTextureFormat(const VideoFrameChromium* frame)
{
switch (frame->format()) {
case VideoFrameChromium::YV12:
@@ -160,56 +183,68 @@ unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
return GraphicsContext3D::INVALID_VALUE;
}
-bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, VideoFrameChromium* frame, unsigned textureFormat)
+bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, const VideoFrameChromium* frame, unsigned textureFormat)
{
ASSERT(context);
ASSERT(frame);
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- IntSize planeTextureSize = frame->requiredTextureSize(plane);
+ IntSize requiredTextureSize = frame->requiredTextureSize(plane);
+ Texture texture = m_textures[plane];
// If the renderer cannot handle this large of a texture, return false.
// FIXME: Remove this test when tiled layers are implemented.
- if (!layerRenderer()->checkTextureSize(planeTextureSize))
+ if (!layerRenderer()->checkTextureSize(requiredTextureSize))
return false;
- if (!m_textures[plane])
- m_textures[plane] = layerRenderer()->createLayerTexture();
-
- if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) {
- allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat);
- m_textureSizes[plane] = planeTextureSize;
- 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);
+ if (texture.isEmpty) {
+ texture.id = layerRenderer()->createLayerTexture();
+ texture.ownedByLayerRenderer = true;
+ texture.isEmpty = false;
+ }
+
+ if (!requiredTextureSize.isZero() && requiredTextureSize != texture.size) {
+ allocateTexture(context, texture.id, requiredTextureSize, textureFormat);
+ texture.size = requiredTextureSize;
+ texture.visibleSize = computeVisibleSize(frame, plane);
}
+ m_textures[plane] = texture;
}
+ return true;
+}
+
+IntSize VideoLayerChromium::computeVisibleSize(const VideoFrameChromium* frame, unsigned plane)
+{
+ int visibleWidth = frame->width(plane);
+ int visibleHeight = 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))
+ --visibleWidth;
+
// 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);
+ if (plane == VideoFrameChromium::yPlane && frame->format() == VideoFrameChromium::YV12) {
+ if (frame->hasPaddingBytes(VideoFrameChromium::uPlane)) {
+ int originalWidth = frame->width(plane);
+ visibleWidth = originalWidth - 2;
+ }
}
- return true;
+ return IntSize(visibleWidth, visibleHeight);
}
-void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat)
+void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat) const
{
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE));
}
-void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data)
+void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data) const
{
ASSERT(context);
GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
@@ -225,33 +260,6 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
}
}
-void VideoLayerChromium::draw()
-{
- if (m_skipsDraw)
- return;
-
- ASSERT(layerRenderer());
- 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(yuvProgram);
- break;
- case VideoFrameChromium::RGBA:
- drawRGBA(rgbaProgram);
- break;
- default:
- // FIXME: Implement other paths.
- notImplemented();
- break;
- }
- releaseCurrentFrame();
-}
-
void VideoLayerChromium::releaseCurrentFrame()
{
if (!m_currentFrame)
@@ -262,86 +270,29 @@ void VideoLayerChromium::releaseCurrentFrame()
resetFrameParameters();
}
-void VideoLayerChromium::drawYUV(const VideoLayerChromium::YUVProgram* program)
-{
- GraphicsContext3D* context = layerRendererContext();
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane]));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane]));
- GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
- GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));
-
- 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(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(program->fragmentShader().signAdjLocation(), 0.5));
-
- GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
-
- 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 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(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->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
-
- 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());
-}
-
void VideoLayerChromium::resetFrameParameters()
{
+ deleteTexturesInUse();
for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
- m_textures[plane] = 0;
- m_textureSizes[plane] = IntSize();
- m_frameSizes[plane] = IntSize();
+ m_textures[plane].id = 0;
+ m_textures[plane].size = IntSize();
+ m_textures[plane].visibleSize = IntSize();
+ m_textures[plane].ownedByLayerRenderer = false;
+ m_textures[plane].isEmpty = true;
}
}
void VideoLayerChromium::saveCurrentFrame(VideoFrameChromium* frame)
{
ASSERT(!m_currentFrame);
+ deleteTexturesInUse();
m_currentFrame = frame;
for (unsigned plane = 0; plane < frame->planes(); plane++) {
- m_textures[plane] = frame->texture(plane);
- m_textureSizes[plane] = frame->requiredTextureSize(plane);
- m_frameSizes[plane] = m_textureSizes[plane];
+ m_textures[plane].id = frame->texture(plane);
+ m_textures[plane].size = frame->requiredTextureSize(plane);
+ m_textures[plane].visibleSize = computeVisibleSize(frame, plane);
+ m_textures[plane].ownedByLayerRenderer = false;
+ m_textures[plane].isEmpty = false;
}
}
diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 2170e13..ef08bd8 100644
--- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -42,19 +42,28 @@ namespace WebCore {
// A Layer that contains a Video element.
class VideoLayerChromium : public LayerChromium {
public:
+ struct Texture {
+ unsigned id;
+ IntSize size;
+ IntSize visibleSize;
+ bool ownedByLayerRenderer;
+ bool isEmpty;
+ };
+
static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
VideoFrameProvider* = 0);
virtual ~VideoLayerChromium();
- virtual void updateContentsIfDirty();
+
+ virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
+
+ virtual void updateCompositorResources();
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();
- typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
- typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
+ virtual void pushPropertiesTo(CCLayerImpl*);
protected:
virtual void cleanupResources();
@@ -63,27 +72,27 @@ protected:
private:
VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
- static unsigned determineTextureFormat(VideoFrameChromium*);
- bool allocateTexturesIfNeeded(GraphicsContext3D*, VideoFrameChromium*, unsigned textureFormat);
- void updateYUVContents(GraphicsContext3D*, const VideoFrameChromium*);
- 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 YUVProgram*);
- void drawRGBA(const RGBAProgram*);
+ static unsigned determineTextureFormat(const VideoFrameChromium*);
+ static IntSize computeVisibleSize(const VideoFrameChromium*, unsigned plane);
+ void deleteTexturesInUse();
+
+ bool allocateTexturesIfNeeded(GraphicsContext3D*, const VideoFrameChromium*, unsigned textureFormat);
+ void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat) const;
+
+ void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data) const;
+
void resetFrameParameters();
void saveCurrentFrame(VideoFrameChromium*);
- static const float yuv2RGB[9];
-
bool m_skipsDraw;
VideoFrameChromium::Format m_frameFormat;
VideoFrameProvider* m_provider;
- VideoFrameChromium* m_currentFrame;
- unsigned m_textures[3];
- IntSize m_textureSizes[3];
- IntSize m_frameSizes[3];
+ Texture m_textures[3];
+
+ // This will be null for the entire duration of video playback if hardware
+ // decoding is not being used.
+ VideoFrameChromium* m_currentFrame;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
index e83d045..652e752 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp
@@ -47,10 +47,11 @@ PassRefPtr<WebGLLayerChromium> WebGLLayerChromium::create(GraphicsLayerChromium*
WebGLLayerChromium::WebGLLayerChromium(GraphicsLayerChromium* owner)
: CanvasLayerChromium(owner)
, m_context(0)
+ , m_textureUpdated(false)
{
}
-void WebGLLayerChromium::updateContentsIfDirty()
+void WebGLLayerChromium::updateCompositorResources()
{
if (!m_contentsDirty)
return;
@@ -68,19 +69,28 @@ void WebGLLayerChromium::updateContentsIfDirty()
m_textureChanged = false;
}
// Update the contents of the texture used by the compositor.
- if (m_contentsDirty) {
+ if (m_contentsDirty && m_textureUpdated) {
m_context->prepareTexture();
+ m_context->markLayerComposited();
m_contentsDirty = false;
+ m_textureUpdated = false;
}
}
+void WebGLLayerChromium::setTextureUpdated()
+{
+ m_textureUpdated = true;
+}
+
void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
{
m_context = const_cast<GraphicsContext3D*>(context);
unsigned int textureId = m_context->platformTexture();
- if (textureId != m_textureId)
+ if (textureId != m_textureId) {
m_textureChanged = true;
+ m_textureUpdated = 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 70be876..33db730 100644
--- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
+++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h
@@ -45,7 +45,8 @@ class WebGLLayerChromium : public CanvasLayerChromium {
public:
static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0);
virtual bool drawsContent() const { return m_context; }
- virtual void updateContentsIfDirty();
+ virtual void updateCompositorResources();
+ void setTextureUpdated();
void setContext(const GraphicsContext3D* context);
@@ -55,6 +56,7 @@ protected:
private:
explicit WebGLLayerChromium(GraphicsLayerChromium* owner);
GraphicsContext3D* m_context;
+ bool m_textureUpdated;
};
}
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
new file mode 100644
index 0000000..649d049
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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/CCCanvasLayerImpl.h"
+
+#include "CanvasLayerChromium.h"
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+CCCanvasLayerImpl::CCCanvasLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+ , m_textureId(0)
+ , m_premultipliedAlpha(true)
+{
+}
+
+CCCanvasLayerImpl::~CCCanvasLayerImpl()
+{
+}
+
+void CCCanvasLayerImpl::draw()
+{
+ ASSERT(layerRenderer());
+ const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram();
+ ASSERT(program && program->initialized());
+ GraphicsContext3D* context = layerRenderer()->context();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
+ 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));
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+
+}
+
+
+void CCCanvasLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "canvas layer texture id: " << m_textureId << " premultiplied: " << m_premultipliedAlpha << "\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
new file mode 100644
index 0000000..8cbf8d1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h
@@ -0,0 +1,61 @@
+/*
+ * 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 CCCanvasLayerImpl_h
+#define CCCanvasLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class CCCanvasLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCCanvasLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCCanvasLayerImpl(owner));
+ }
+ virtual ~CCCanvasLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setTextureId(unsigned id) { m_textureId = id; }
+ void setPremultipliedAlpha(bool premultipliedAlpha) { m_premultipliedAlpha = premultipliedAlpha; }
+private:
+ explicit CCCanvasLayerImpl(LayerChromium*);
+
+ unsigned m_textureId;
+ bool m_premultipliedAlpha;
+};
+
+}
+
+#endif // CCCanvasLayerImpl_h
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
index 604ef61..404944b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp
@@ -66,8 +66,8 @@ void CCHeadsUpDisplay::draw()
// 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()));
+ hudSize.setWidth(min(2048, m_layerRenderer->viewportSize().width()));
+ hudSize.setHeight(min(2048, m_layerRenderer->viewportSize().height()));
} else {
hudSize.setWidth(512);
hudSize.setHeight(128);
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
index dbac22a..d56f8ab 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h
@@ -53,7 +53,7 @@ public:
void setShowPlatformLayerTree(bool enable) { m_showPlatformLayerTree = enable; }
bool showPlatformLayerTree() const { return m_showPlatformLayerTree; }
- bool enabled() const { return true || m_showPlatformLayerTree || m_showFPSCounter; }
+ bool enabled() const { return m_showPlatformLayerTree || m_showFPSCounter; }
void draw();
private:
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
index a0ad0fb..9411e5a 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp
@@ -62,13 +62,18 @@ namespace WebCore {
CCLayerImpl::CCLayerImpl(LayerChromium* owner)
: m_owner(owner)
+ , m_anchorPoint(0.5, 0.5)
+ , m_anchorPointZ(0)
+ , m_doubleSided(true)
+ , m_masksToBounds(false)
+ , m_opacity(1.0)
+ , m_preserves3D(false)
#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)
@@ -107,7 +112,18 @@ RenderSurfaceChromium* CCLayerImpl::createRenderSurface()
return m_renderSurface.get();
}
-// These belong on CCLayerImpl, but should be subclased by each type and not defer to the LayerChromium subtypes.
+bool CCLayerImpl::descendantsDrawsContent()
+{
+ const Vector<RefPtr<LayerChromium> >& sublayers = m_owner->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); ++i) {
+ sublayers[i]->createCCLayerImplIfNeeded();
+ if (sublayers[i]->ccLayerImpl()->drawsContent() || sublayers[i]->ccLayerImpl()->descendantsDrawsContent())
+ return true;
+ }
+ return false;
+}
+
+// These belong on CCLayerImpl, but should be overridden by each type and not defer to the LayerChromium subtypes.
bool CCLayerImpl::drawsContent() const
{
return m_owner->drawsContent();
@@ -118,6 +134,11 @@ void CCLayerImpl::draw()
return m_owner->draw();
}
+void CCLayerImpl::updateCompositorResources()
+{
+ return m_owner->updateCompositorResources();
+}
+
void CCLayerImpl::unreserveContentsTexture()
{
m_owner->unreserveContentsTexture();
@@ -167,7 +188,7 @@ void CCLayerImpl::drawDebugBorder()
GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short)));
}
-static void writeIndent(TextStream& ts, int indent)
+void CCLayerImpl::writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
ts << " ";
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
index 6892976..96c4f1b 100644
--- a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h
@@ -49,7 +49,7 @@ public:
return adoptRef(new CCLayerImpl(owner));
}
// When this class gets subclasses, remember to add 'virtual' here.
- ~CCLayerImpl();
+ virtual ~CCLayerImpl();
#ifndef NDEBUG
int debugID() const { return m_debugID; }
@@ -59,13 +59,43 @@ public:
CCLayerImpl* maskLayer() const;
CCLayerImpl* replicaLayer() const;
- void draw();
- bool drawsContent() const;
+ virtual void draw();
+ virtual void updateCompositorResources();
void unreserveContentsTexture();
void bindContentsTexture();
+ // Returns true if this layer has content to draw.
+ virtual bool drawsContent() const;
+
+ // Returns true if any of the layer's descendants has content to draw.
+ bool descendantsDrawsContent();
+
void cleanupResources();
+ void setAnchorPoint(const FloatPoint& anchorPoint) { m_anchorPoint = anchorPoint; }
+ const FloatPoint& anchorPoint() const { return m_anchorPoint; }
+
+ void setAnchorPointZ(float anchorPointZ) { m_anchorPointZ = anchorPointZ; }
+ float anchorPointZ() const { return m_anchorPointZ; }
+
+ void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; }
+ bool masksToBounds() const { return m_masksToBounds; }
+
+ void setOpacity(float opacity) { m_opacity = opacity; }
+ float opacity() const { return m_opacity; }
+
+ void setPosition(const FloatPoint& position) { m_position = position; }
+ const FloatPoint& position() const { return m_position; }
+
+ void setPreserves3D(bool preserves3D) { m_preserves3D = preserves3D; }
+ bool preserves3D() const { return m_preserves3D; }
+
+ void setSublayerTransform(const TransformationMatrix& sublayerTransform) { m_sublayerTransform = sublayerTransform; }
+ const TransformationMatrix& sublayerTransform() const { return m_sublayerTransform; }
+
+ void setTransform(const TransformationMatrix& transform) { m_transform = transform; }
+ const TransformationMatrix& transform() const { return m_transform; }
+
void setName(const String& name) { m_name = name; }
const String& name() const { return m_name; }
@@ -108,11 +138,30 @@ public:
virtual void dumpLayerProperties(TextStream&, int indent) const;
-private:
+protected:
// For now, CCLayers are owned directly by a LayerChromium.
LayerChromium* m_owner;
explicit CCLayerImpl(LayerChromium*);
+ static void writeIndent(TextStream&, int indent);
+
+private:
+ // Properties synchronized from the associated LayerChromium.
+ FloatPoint m_anchorPoint;
+ float m_anchorPointZ;
+ IntSize m_bounds;
+
+ // Whether the "back" of this layer should draw.
+ bool m_doubleSided;
+
+ bool m_masksToBounds;
+ float m_opacity;
+ FloatPoint m_position;
+ bool m_preserves3D;
+ TransformationMatrix m_sublayerTransform;
+ TransformationMatrix m_transform;
+
+ // Properties owned exclusively by this CCLayerImpl.
// Debugging.
#ifndef NDEBUG
int m_debugID;
@@ -131,17 +180,12 @@ private:
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.
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
new file mode 100644
index 0000000..4aef639
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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/CCPluginLayerImpl.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include "PluginLayerChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+CCPluginLayerImpl::CCPluginLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+ , m_textureId(0)
+{
+}
+
+CCPluginLayerImpl::~CCPluginLayerImpl()
+{
+}
+
+void CCPluginLayerImpl::draw()
+{
+ ASSERT(layerRenderer());
+ const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram();
+ ASSERT(program && program->initialized());
+ GraphicsContext3D* context = layerRenderer()->context();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
+
+ // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
+ // where it will only happen once per texture.
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
+ GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
+
+ layerRenderer()->useShader(program->program());
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+}
+
+
+void CCPluginLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "plugin layer texture id: " << m_textureId << "\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
new file mode 100644
index 0000000..65eb5b7
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCPluginLayerImpl.h
@@ -0,0 +1,60 @@
+/*
+ * 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 CCPluginLayerImpl_h
+#define CCPluginLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class CCPluginLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCPluginLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCPluginLayerImpl(owner));
+ }
+ virtual ~CCPluginLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setTextureId(unsigned id) { m_textureId = id; }
+
+private:
+ explicit CCPluginLayerImpl(LayerChromium*);
+
+ unsigned m_textureId;
+};
+
+}
+
+#endif // CCPluginLayerImpl_h
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
new file mode 100644
index 0000000..eb3612b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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/CCVideoLayerImpl.h"
+
+#include "GraphicsContext3D.h"
+#include "LayerRendererChromium.h"
+#include "NotImplemented.h"
+#include "VideoLayerChromium.h"
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// These values are magic numbers that are used in the transformation
+// from YUV to RGB color values.
+// They are taken from the following webpage:
+// http://www.fourcc.org/fccyvrgb.php
+const float CCVideoLayerImpl::yuv2RGB[9] = {
+ 1.164f, 1.164f, 1.164f,
+ 0.f, -.391f, 2.018f,
+ 1.596f, -.813f, 0.f,
+};
+
+// These values map to 16, 128, and 128 respectively, and are computed
+// as a fraction over 256 (e.g. 16 / 256 = 0.0625).
+// They are used in the YUV to RGBA conversion formula:
+// Y - 16 : Gives 16 values of head and footroom for overshooting
+// U - 128 : Turns unsigned U into signed U [-128,127]
+// V - 128 : Turns unsigned V into signed V [-128,127]
+const float CCVideoLayerImpl::yuvAdjust[3] = {
+ -0.0625f,
+ -0.5f,
+ -0.5f,
+};
+
+CCVideoLayerImpl::CCVideoLayerImpl(LayerChromium* owner)
+ : CCLayerImpl(owner)
+{
+}
+
+CCVideoLayerImpl::~CCVideoLayerImpl()
+{
+ cleanupResources();
+}
+
+void CCVideoLayerImpl::setTexture(size_t i, VideoLayerChromium::Texture texture)
+{
+ ASSERT(i < 3);
+ m_textures[i] = texture;
+}
+
+void CCVideoLayerImpl::draw()
+{
+ if (m_skipsDraw)
+ return;
+
+ ASSERT(layerRenderer());
+ 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(yuvProgram);
+ break;
+ case VideoFrameChromium::RGBA:
+ drawRGBA(rgbaProgram);
+ break;
+ default:
+ // FIXME: Implement other paths.
+ notImplemented();
+ break;
+ }
+}
+
+void CCVideoLayerImpl::drawYUV(const CCVideoLayerImpl::YUVProgram* program) const
+{
+ GraphicsContext3D* context = layerRenderer()->context();
+ VideoLayerChromium::Texture yTexture = m_textures[VideoFrameChromium::yPlane];
+ VideoLayerChromium::Texture uTexture = m_textures[VideoFrameChromium::uPlane];
+ VideoLayerChromium::Texture vTexture = m_textures[VideoFrameChromium::vPlane];
+
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id));
+
+ layerRenderer()->useShader(program->program());
+
+ float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width();
+ // Arbitrarily take the u sizes because u and v dimensions are identical.
+ float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width();
+ GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
+ GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));
+
+ GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
+ GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
+ GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));
+
+ GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
+ GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));
+
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+
+ // Reset active texture back to texture 0.
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+}
+
+void CCVideoLayerImpl::drawRGBA(const CCVideoLayerImpl::RGBAProgram* program) const
+{
+ GraphicsContext3D* context = layerRenderer()->context();
+ VideoLayerChromium::Texture texture = m_textures[VideoFrameChromium::rgbPlane];
+
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, texture.id));
+
+ layerRenderer()->useShader(program->program());
+ float widthScaleFactor = static_cast<float>(texture.visibleSize.width()) / texture.size.width();
+ GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));
+
+ GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
+
+ LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ program->vertexShader().matrixLocation(),
+ program->fragmentShader().alphaLocation());
+}
+
+
+void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "video layer\n";
+ CCLayerImpl::dumpLayerProperties(ts, indent);
+}
+
+}
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
new file mode 100644
index 0000000..62f8778
--- /dev/null
+++ b/Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
@@ -0,0 +1,75 @@
+/*
+ * 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 CCVideoLayerImpl_h
+#define CCVideoLayerImpl_h
+
+#include "ProgramBinding.h"
+#include "ShaderChromium.h"
+#include "VideoFrameChromium.h"
+#include "VideoLayerChromium.h"
+#include "cc/CCLayerImpl.h"
+
+namespace WebCore {
+
+class VideoFrameProvider;
+
+class CCVideoLayerImpl : public CCLayerImpl {
+public:
+ static PassRefPtr<CCVideoLayerImpl> create(LayerChromium* owner)
+ {
+ return adoptRef(new CCVideoLayerImpl(owner));
+ }
+ virtual ~CCVideoLayerImpl();
+
+ typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram;
+ typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram;
+
+ virtual void draw();
+
+ virtual void dumpLayerProperties(TextStream&, int indent) const;
+
+ void setSkipsDraw(bool skipsDraw) { m_skipsDraw = skipsDraw; }
+ void setFrameFormat(VideoFrameChromium::Format format) { m_frameFormat = format; }
+ void setTexture(size_t, VideoLayerChromium::Texture);
+
+private:
+ explicit CCVideoLayerImpl(LayerChromium*);
+
+ void drawYUV(const YUVProgram*) const;
+ void drawRGBA(const RGBAProgram*) const;
+
+ static const float yuv2RGB[9];
+ static const float yuvAdjust[3];
+
+ bool m_skipsDraw;
+ VideoFrameChromium::Format m_frameFormat;
+ VideoLayerChromium::Texture m_textures[3];
+};
+
+}
+
+#endif // CCVideoLayerImpl_h
+