summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/chromium
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/chromium')
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp4
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp1
-rw-r--r--WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp104
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp48
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp7
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h12
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp155
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h6
8 files changed, 259 insertions, 78 deletions
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 9538a8d..48cf9d2 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -274,7 +274,7 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
// If there is a non-blur shadow and both the fill color and shadow color
// are opaque, handle without skia.
IntSize shadowSize;
- int shadowBlur;
+ float shadowBlur;
Color shadowColor;
if (m_graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor)) {
// If there is a shadow and this code is reached, windowsCanHandleDrawTextShadow()
@@ -484,7 +484,7 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// If there is a non-blur shadow and both the fill color and shadow color
// are opaque, handle without skia.
IntSize shadowSize;
- int shadowBlur;
+ float shadowBlur;
Color shadowColor;
if (graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor) && windowsCanHandleDrawTextShadow(graphicsContext)) {
COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 7b22bad..0a5aec5 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -143,6 +143,7 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
break;
}
+ paint->setEmbeddedBitmapText(m_style.useBitmaps);
paint->setTextSize(SkFloatToScalar(ts));
paint->setTypeface(m_typeface);
paint->setFakeBoldText(m_fakeBold);
diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
index 8dba49e..78170a9 100644
--- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2007, 2008, Google Inc. All rights reserved.
+ * Copyright (c) 2006, 2007, 2008, 2009, 2010, 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
@@ -44,6 +44,25 @@ namespace WebCore {
namespace {
+bool isFontPresent(const UChar* fontName)
+{
+ HFONT hfont = CreateFont(12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ fontName);
+ if (!hfont)
+ return false;
+ HDC dc = GetDC(0);
+ HGDIOBJ oldFont = static_cast<HFONT>(SelectObject(dc, hfont));
+ WCHAR actualFontName[LF_FACESIZE];
+ GetTextFace(dc, LF_FACESIZE, actualFontName);
+ actualFontName[LF_FACESIZE - 1] = 0;
+ SelectObject(dc, oldFont);
+ DeleteObject(hfont);
+ ReleaseDC(0, dc);
+ // We don't have to worry about East Asian fonts with locale-dependent
+ // names here for now.
+ return !wcscmp(fontName, actualFontName);
+}
+
// A simple mapping from UScriptCode to family name. This is a sparse array,
// which works well since the range of UScriptCode values is small.
typedef const UChar* ScriptToFontMap[USCRIPT_CODE_LIMIT];
@@ -55,10 +74,14 @@ void initializeScriptFontMap(ScriptToFontMap& scriptFontMap)
const UChar* family;
};
- const static FontMap fontMap[] = {
+ static const FontMap fontMap[] = {
{USCRIPT_LATIN, L"times new roman"},
{USCRIPT_GREEK, L"times new roman"},
{USCRIPT_CYRILLIC, L"times new roman"},
+ // FIXME: Consider trying new Vista fonts before XP fonts for CJK.
+ // Some Vista users do want to use Vista cleartype CJK fonts. If we
+ // did, the results of tests with CJK characters would have to be
+ // regenerated for Vista.
{USCRIPT_SIMPLIFIED_HAN, L"simsun"},
{USCRIPT_TRADITIONAL_HAN, L"pmingliu"},
{USCRIPT_HIRAGANA, L"ms pgothic"},
@@ -72,32 +95,81 @@ void initializeScriptFontMap(ScriptToFontMap& scriptFontMap)
{USCRIPT_BENGALI, L"vrinda"},
{USCRIPT_GURMUKHI, L"raavi"},
{USCRIPT_GUJARATI, L"shruti"},
- {USCRIPT_ORIYA, L"kalinga"},
{USCRIPT_TAMIL, L"latha"},
{USCRIPT_TELUGU, L"gautami"},
{USCRIPT_KANNADA, L"tunga"},
- {USCRIPT_MALAYALAM, L"kartika"},
- {USCRIPT_LAO, L"dokchampa"},
- {USCRIPT_TIBETAN, L"microsoft himalaya"},
{USCRIPT_GEORGIAN, L"sylfaen"},
{USCRIPT_ARMENIAN, L"sylfaen"},
- {USCRIPT_ETHIOPIC, L"nyala"},
+ {USCRIPT_THAANA, L"mv boli"},
{USCRIPT_CANADIAN_ABORIGINAL, L"euphemia"},
{USCRIPT_CHEROKEE, L"plantagenet cherokee"},
- {USCRIPT_YI, L"microsoft yi balti"},
- {USCRIPT_SINHALA, L"iskoola pota"},
- {USCRIPT_SYRIAC, L"estrangelo edessa"},
- {USCRIPT_KHMER, L"daunpenh"},
- {USCRIPT_THAANA, L"mv boli"},
{USCRIPT_MONGOLIAN, L"mongolian balti"},
- {USCRIPT_MYANMAR, L"padauk"},
// For USCRIPT_COMMON, we map blocks to scripts when
// that makes sense.
};
-
+
+ struct ScriptToFontFamilies {
+ UScriptCode script;
+ const UChar** families;
+ };
+
+ // Kartika on Vista or earlier lacks the support for Chillu
+ // letters added to Unicode 5.1.
+ // Try AnjaliOldLipi (a very widely used Malaylalam font with the full
+ // Unicode 5.x support) before falling back to Kartika.
+ static const UChar* malayalamFonts[] = {L"AnjaliOldLipi", L"Lohit Malayalam", L"Kartika", L"Rachana", 0};
+ // Try Khmer OS before Vista fonts because 'Khmer OS' goes along better
+ // with Latin and looks better/larger for the same size.
+ static const UChar* khmerFonts[] = {L"Khmer OS", L"MoolBoran", L"DaunPenh", L"Code2000", 0};
+ // For the following 6 scripts, two or fonts are listed. The fonts in
+ // the 1st slot are not available on Windows XP. To support these
+ // scripts on XP, listed in the rest of slots are widely used
+ // fonts.
+ static const UChar* ethiopicFonts[] = {L"Nyala", L"Abyssinica SIL", L"Ethiopia Jiret", L"Visual Geez Unicode", L"GF Zemen Unicode", 0};
+ static const UChar* oriyaFonts[] = {L"Kalinga", L"ori1Uni", L"Lohit Oriya", 0};
+ static const UChar* laoFonts[] = {L"DokChampa", L"Saysettha OT", L"Phetsarath OT", L"Code2000", 0};
+ static const UChar* tibetanFonts[] = {L"Microsoft Himalaya", L"Jomolhari", L"Tibetan Machine Uni", 0};
+ static const UChar* sinhalaFonts[] = {L"Iskoola Pota", L"AksharUnicode", 0};
+ static const UChar* yiFonts[] = {L"Microsoft Yi Balti", L"Nuosu SIL", L"Code2000", 0};
+ // http://www.bethmardutho.org/support/meltho/download/index.php
+ static const UChar* syriacFonts[] = {L"Estrangelo Edessa", L"Estrangelo Nisibin", L"Code2000", 0};
+ // No Myanmar/Burmese font is shipped with Windows, yet. Try a few
+ // widely available/used ones that supports Unicode 5.1 or later.
+ static const UChar* myanmarFonts[] = {L"Padauk", L"Parabaik", L"Myanmar3", L"Code2000", 0};
+
+ static const ScriptToFontFamilies scriptToFontFamilies[] = {
+ {USCRIPT_MALAYALAM, malayalamFonts},
+ {USCRIPT_KHMER, khmerFonts},
+ {USCRIPT_ETHIOPIC, ethiopicFonts},
+ {USCRIPT_ORIYA, oriyaFonts},
+ {USCRIPT_LAO, laoFonts},
+ {USCRIPT_TIBETAN, tibetanFonts},
+ {USCRIPT_SINHALA, sinhalaFonts},
+ {USCRIPT_YI, yiFonts},
+ {USCRIPT_SYRIAC, syriacFonts},
+ {USCRIPT_MYANMAR, myanmarFonts},
+ };
+
for (int i = 0; i < sizeof(fontMap) / sizeof(fontMap[0]); ++i)
scriptFontMap[fontMap[i].script] = fontMap[i].family;
+ // FIXME: Instead of scanning the hard-coded list, we have to
+ // use EnumFont* to 'inspect' fonts to pick up fonts covering scripts
+ // when it's possible (e.g. using OS/2 table). If we do that, this
+ // had better be pulled out of here.
+ for (int i = 0; i < sizeof(scriptToFontFamilies) / sizeof(scriptToFontFamilies[0]); ++i) {
+ UScriptCode script = scriptToFontFamilies[i].script;
+ scriptFontMap[script] = 0;
+ const UChar** familyPtr = scriptToFontFamilies[i].families;
+ while (*familyPtr) {
+ if (isFontPresent(*familyPtr)) {
+ scriptFontMap[script] = *familyPtr;
+ break;
+ }
+ ++familyPtr;
+ }
+ }
+
// Initialize the locale-dependent mapping.
// Since Chrome synchronizes the ICU default locale with its UI locale,
// this ICU locale tells the current UI locale of Chrome.
@@ -198,7 +270,7 @@ struct FontData {
// in the 1st pass. Need to experiment further.
typedef HashMap<String, FontData> FontDataCache;
-} // namespace
+} // namespace
// FIXME: this is font fallback code version 0.1
// - Cover all the scripts
@@ -363,4 +435,4 @@ int getStyleFromLogfont(const LOGFONT* logfont)
(logfont->lfWeight >= 700 ? FontStyleBold : FontStyleNormal);
}
-} // namespace WebCore
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 37ea485..23aeefa 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -474,7 +474,50 @@ void GraphicsLayerChromium::updateBackfaceVisibility()
void GraphicsLayerChromium::updateLayerPreserves3D()
{
- // FIXME: implement
+ if (m_preserves3D && !m_transformLayer) {
+ // Create the transform layer.
+ m_transformLayer = LayerChromium::create(LayerChromium::TransformLayer, this);
+
+ // Copy the position from this layer.
+ updateLayerPosition();
+ updateLayerSize();
+ updateAnchorPoint();
+ updateTransform();
+ updateChildrenTransform();
+
+ m_layer->setPosition(FloatPoint(m_size.width() / 2.0f, m_size.height() / 2.0f));
+
+ m_layer->setAnchorPoint(FloatPoint(0.5f, 0.5f));
+ TransformationMatrix identity;
+ m_layer->setTransform(identity);
+
+ // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer.
+ m_layer->setOpacity(1);
+
+ // Move this layer to be a child of the transform layer.
+ if (m_layer->superlayer())
+ m_layer->superlayer()->replaceSublayer(m_layer.get(), m_transformLayer.get());
+ m_transformLayer->addSublayer(m_layer.get());
+
+ updateSublayerList();
+ } else if (!m_preserves3D && m_transformLayer) {
+ // Relace the transformLayer in the parent with this layer.
+ m_layer->removeFromSuperlayer();
+ m_transformLayer->superlayer()->replaceSublayer(m_transformLayer.get(), m_layer.get());
+
+ // Release the transform layer.
+ m_transformLayer = 0;
+
+ updateLayerPosition();
+ updateLayerSize();
+ updateAnchorPoint();
+ updateTransform();
+ updateChildrenTransform();
+
+ updateSublayerList();
+ }
+
+ updateOpacityOnLayer();
}
void GraphicsLayerChromium::updateLayerDrawsContent()
@@ -527,8 +570,7 @@ void GraphicsLayerChromium::updateContentsRect()
if (!m_contentsLayer)
return;
- // The position of the layer is the center of quad.
- m_contentsLayer->setPosition(FloatPoint(m_contentsRect.x() + m_contentsRect.width() / 2, m_contentsRect.y() + m_contentsRect.height() / 2));
+ m_contentsLayer->setPosition(FloatPoint(m_contentsRect.x(), m_contentsRect.y()));
m_contentsLayer->setBounds(IntSize(m_contentsRect.width(), m_contentsRect.height()));
}
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index b08df82..5e71e49 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -118,6 +118,10 @@ void LayerChromium::updateTextureContents(unsigned int textureId)
OwnPtr<PlatformContextSkia> skiaContext;
OwnPtr<GraphicsContext> graphicsContext;
if (drawsContent()) { // Layer contents must be drawn into a canvas.
+ // Clip the dirtyRect to the size of the layer to avoid drawing outside
+ // the bounds of the backing texture.
+ dirtyRect.intersect(IntRect(IntPoint(0, 0), m_bounds));
+
canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
skiaContext.set(new PlatformContextSkia(canvas.get()));
@@ -135,8 +139,7 @@ void LayerChromium::updateTextureContents(unsigned int textureId)
m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
skiaBitmap = &bitmap;
- requiredTextureSize = IntSize(max(m_bounds.width(), dirtyRect.width()),
- max(m_bounds.height(), dirtyRect.height()));
+ requiredTextureSize = m_bounds;
} else { // Layer is a container.
// The layer contains an Image.
NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(contents());
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 59952eb..7af7e9b 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -158,8 +158,16 @@ public:
void setContents(NativeImagePtr contents);
NativeImagePtr contents() const { return m_contents; }
+ void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
+ const TransformationMatrix& drawTransform() const { return m_drawTransform; }
+
+ void setDrawOpacity(float opacity) { m_drawOpacity = opacity; }
+ float drawOpacity() const { return m_drawOpacity; }
+
bool drawsContent() { return m_owner && m_owner->drawsContent(); }
+ bool preserves3D() { return m_owner && m_owner->preserves3D(); }
+
void setLayerRenderer(LayerRendererChromium*);
private:
@@ -203,12 +211,16 @@ private:
TransformationMatrix m_transform;
TransformationMatrix m_sublayerTransform;
+ TransformationMatrix m_drawTransform;
+
uint32_t m_edgeAntialiasingMask;
float m_opacity;
float m_zPosition;
float m_anchorPointZ;
float m_borderWidth;
+ float m_drawOpacity;
+
unsigned int m_allocatedTextureId;
IntSize m_allocatedTextureSize;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index dfb6078..73311be 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -156,6 +156,13 @@ static GLuint createLayerTexture()
return textureId;
}
+static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
+{
+ const TransformationMatrix& transformA = a->drawTransform();
+ const TransformationMatrix& transformB = b->drawTransform();
+
+ return transformA.m43() < transformB.m43();
+}
PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(Page* page)
{
@@ -173,6 +180,7 @@ LayerRendererChromium::LayerRendererChromium(Page* page)
, m_page(page)
, m_rootLayerTextureWidth(0)
, m_rootLayerTextureHeight(0)
+ , m_scrollPosition(IntPoint(-1, -1))
{
m_quadVboIds[Vertices] = m_quadVboIds[LayerElements] = 0;
m_hardwareCompositing = (initGL() && initializeSharedGLObjects());
@@ -284,6 +292,9 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
+ if (m_scrollPosition == IntPoint(-1, -1))
+ m_scrollPosition = scrollPosition;
+
IntPoint scrollDelta = toPoint(scrollPosition - m_scrollPosition);
// Scroll only when the updateRect contains pixels for the newly uncovered region to avoid flashing.
if ((scrollDelta.x() && updateRect.width() >= abs(scrollDelta.x()) && updateRect.height() >= contentRect.height())
@@ -358,19 +369,26 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
checkGLError();
- // FIXME: Sublayers need to be sorted in Z to get the correct transparency effect.
-
- // Enable scissoring to avoid rendering composited layers over the scrollbars.
- glEnable(GL_SCISSOR_TEST);
- glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height());
-
// Translate all the composited layers by the scroll position.
TransformationMatrix matrix;
matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
+
float opacity = 1;
+ m_layerList.shrink(0);
const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
for (size_t i = 0; i < sublayers.size(); i++)
- compositeLayersRecursive(sublayers[i].get(), matrix, opacity, visibleRect);
+ updateLayersRecursive(sublayers[i].get(), matrix, opacity, visibleRect);
+
+ // Sort layers by the z coordinate of their center so that layers further
+ // away get drawn first.
+ std::stable_sort(m_layerList.begin(), m_layerList.end(), compareLayerZ);
+
+ // Enable scissoring to avoid rendering composited layers over the scrollbars.
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height());
+
+ for (size_t j = 0; j < m_layerList.size(); j++)
+ drawLayer(m_layerList[j]);
glDisable(GL_SCISSOR_TEST);
@@ -464,65 +482,108 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform
return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
}
-void LayerRendererChromium::compositeLayersRecursive(LayerChromium* layer, const TransformationMatrix& matrix, float opacity, const IntRect& visibleRect)
+// Updates and caches the layer transforms and opacity values that will be used
+// when rendering them.
+void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect)
{
- static GLfloat glMatrix[16];
-
// Compute the new matrix transformation that will be applied to this layer and
- // all its sublayers.
- // The basic transformation chain for the layer is (using the Matrix x Vector order):
- // M = M[p] * T[l] * T[a] * M[l] * T[-a]
+ // all its sublayers. It's important to remember that the layer's position
+ // is the position of the layer's anchor point. Also, the coordinate system used
+ // assumes that the origin is at the lower left even though the coordinates the browser
+ // gives us for the layers are for the upper left corner. The Y flip happens via
+ // the orthographic projection applied at render time.
+ // The transformation chain for the layer is (using the Matrix x Vector order):
+ // M = M[p] * Tr[l] * M[l] * Tr[c]
// Where M[p] is the parent matrix passed down to the function
- // T[l] is the translation of the layer's center
- // T[a] and T[-a] is a translation/inverse translation by the anchor point
- // M[l] is the layer's matrix
+ // Tr[l] is the translation matrix locating the layer's anchor point
+ // Tr[c] is the translation offset between the anchor point and the center of the layer
+ // M[l] is the layer's matrix (applied at the anchor point)
+ // This transform creates a coordinate system whose origin is the center of the layer.
// Note that the final matrix used by the shader for the layer is P * M * S . This final product
- // is effectively computed in drawTexturedQuad().
+ // is computed in drawTexturedQuad().
// 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();
- float anchorX = (anchorPoint.x() - 0.5) * bounds.width();
- float anchorY = (0.5 - anchorPoint.y()) * bounds.height();
+
+ // Offset between anchor point and the center of the quad.
+ float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
+ float centerOffsetY = (0.5 - anchorPoint.y()) * bounds.height();
// M = M[p]
- TransformationMatrix localMatrix = matrix;
- // M = M[p] * T[l]
- localMatrix.translate3d(position.x(), position.y(), 0);
- // M = M[p] * T[l] * T[a]
- localMatrix.translate3d(anchorX, anchorY, 0);
- // M = M[p] * T[l] * T[a] * M[l]
+ TransformationMatrix localMatrix = parentMatrix;
+ // M = M[p] * Tr[l]
+ localMatrix.translate3d(position.x(), position.y(), layer->anchorPointZ());
+ // M = M[p] * Tr[l] * M[l]
localMatrix.multLeft(layer->transform());
- // M = M[p] * T[l] * T[a] * M[l] * T[-a]
- localMatrix.translate3d(-anchorX, -anchorY, 0);
+ // M = M[p] * Tr[l] * M[l] * Tr[c]
+ localMatrix.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
+
+ // Check if the layer falls within the visible bounds of the page.
+ bool layerVisible = isLayerVisible(layer, localMatrix, visibleRect);
+
+ bool layerHasContent = layer->drawsContent() || layer->contents();
bool skipLayer = false;
if (bounds.width() > 2048 || bounds.height() > 2048) {
- LOG(LayerRenderer, "Skipping layer with size %d %d", bounds.width(), bounds.height());
+ if (layerHasContent)
+ LOG(LayerRenderer, "Skipping layer with size %d %d", bounds.width(), bounds.height());
skipLayer = true;
}
// Calculate the layer's opacity.
opacity *= layer->opacity();
- bool layerVisible = isLayerVisible(layer, localMatrix, visibleRect);
+ layer->setDrawTransform(localMatrix);
+ layer->setDrawOpacity(opacity);
+ if (layerVisible && !skipLayer)
+ m_layerList.append(layer);
+
+ // Flatten to 2D if the layer doesn't preserve 3D.
+ if (!layer->preserves3D()) {
+ localMatrix.setM13(0);
+ localMatrix.setM23(0);
+ localMatrix.setM31(0);
+ localMatrix.setM32(0);
+ localMatrix.setM33(1);
+ localMatrix.setM34(0);
+ localMatrix.setM43(0);
+ }
+
+ // Apply the sublayer transform at the center of the layer.
+ localMatrix.multLeft(layer->sublayerTransform());
+
+ // The origin of the sublayers is actually the bottom left corner of the layer
+ // (or top left when looking it it from the browser's pespective) instead of the center.
+ // The matrix passed down to the sublayers is therefore:
+ // M[s] = M * Tr[-center]
+ localMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
+
+ const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
+ for (size_t i = 0; i < sublayers.size(); i++)
+ updateLayersRecursive(sublayers[i].get(), localMatrix, opacity, visibleRect);
+}
+
+void LayerRendererChromium::drawLayer(LayerChromium* layer)
+{
+ const TransformationMatrix& localMatrix = layer->drawTransform();
+ IntSize bounds = layer->bounds();
// Note that there are two types of layers:
- // 1. Layers that have their own GraphicsContext and can draw their contents on demand (layer->drawsContent() == true).
- // 2. Layers that are just containers of images/video/etc that don't own a GraphicsContext (layer->contents() == true).
- if ((layer->drawsContent() || layer->contents()) && !skipLayer && layerVisible) {
+ // 1. Layers that draw their own content via the GraphicsContext (layer->drawsContent() == true).
+ // 2. Layers that are pure containers of images/video/etc whose content is simply
+ // copied into the backing texture (layer->contents() == true).
+ if (layer->drawsContent() || layer->contents()) {
int textureId = getTextureId(layer);
// If no texture has been created for the layer yet then create one now.
if (textureId == -1)
textureId = assignTextureForLayer(layer);
// Redraw the contents of the layer if necessary.
- if ((layer->drawsContent() || layer->contents()) && layer->contentsDirty()) {
- // Update the contents of the layer before taking a snapshot. For layers that
- // are simply containers, the following call just clears the dirty flag but doesn't
- // actually do any draws/copies.
+ if (layer->contentsDirty()) {
+ // Update the backing texture contents for any dirty portion of the layer.
layer->updateTextureContents(textureId);
}
@@ -533,22 +594,11 @@ void LayerRendererChromium::compositeLayersRecursive(LayerChromium* layer, const
glBindTexture(GL_TEXTURE_2D, textureId);
- drawTexturedQuad(localMatrix, bounds.width(), bounds.height(), opacity, false);
+ drawTexturedQuad(localMatrix, bounds.width(), bounds.height(), layer->drawOpacity(), false);
}
// Draw the debug border if there is one.
drawDebugBorder(layer, localMatrix);
-
- // Apply the sublayer transform.
- localMatrix.multLeft(layer->sublayerTransform());
-
- // The origin of the sublayers is actually the left top corner of the layer
- // instead of the center. The matrix passed down to the sublayers is therefore:
- // M[s] = M * T[-center]
- localMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
- const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
- for (size_t i = 0; i < sublayers.size(); i++)
- compositeLayersRecursive(sublayers[i].get(), localMatrix, opacity, visibleRect);
}
bool LayerRendererChromium::makeContextCurrent()
@@ -590,8 +640,7 @@ bool LayerRendererChromium::initializeSharedGLObjects()
" v_texCoord = a_texCoord; \n"
"} \n";
char fragmentShaderString[] =
- // FIXME: Re-introduce precision qualifier when we need GL ES shaders.
- "//precision mediump float; \n"
+ "precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"uniform float alpha; \n"
@@ -605,8 +654,7 @@ bool LayerRendererChromium::initializeSharedGLObjects()
// from fragmentShaderString in that it doesn't swizzle the colors and doesn't
// take an alpha value.
char scrollFragmentShaderString[] =
- // FIXME: Re-introduce precision qualifier when we need GL ES shaders.
- "//precision mediump float; \n"
+ "precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
@@ -624,8 +672,7 @@ bool LayerRendererChromium::initializeSharedGLObjects()
" gl_Position = matrix * a_position; \n"
"} \n";
char borderFragmentShaderString[] =
- // FIXME: Re-introduce precision qualifier when we need GL ES shaders.
- "//precision mediump float; \n"
+ "precision mediump float; \n"
"uniform vec4 color; \n"
"void main() \n"
"{ \n"
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index eb66dac..a2e3427 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -74,7 +74,9 @@ public:
GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); }
private:
- void compositeLayersRecursive(LayerChromium*, const TransformationMatrix&, float opacity, const IntRect& visibleRect);
+ void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity, const IntRect& visibleRect);
+
+ void drawLayer(LayerChromium*);
void drawDebugBorder(LayerChromium*, const TransformationMatrix&);
@@ -120,6 +122,8 @@ private:
RefPtr<LayerChromium> m_rootLayer;
+ Vector<LayerChromium*> m_layerList;
+
bool m_needsDisplay;
IntPoint m_scrollPosition;
bool m_hardwareCompositing;