diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index bc37201..54c6ac2 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -40,6 +40,8 @@ using namespace std; +static int minTextureSize = 16; + namespace WebCore { PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border) @@ -69,8 +71,10 @@ GraphicsContext3D* LayerTilerChromium::layerRendererContext() const return layerRenderer()->context(); } -void LayerTilerChromium::setTileSize(const IntSize& size) +void LayerTilerChromium::setTileSize(const IntSize& requestedSize) { + IntSize size(max(minTextureSize, requestedSize.width()), max(minTextureSize, requestedSize.height())); + if (m_tileSize == size) return; @@ -81,6 +85,12 @@ void LayerTilerChromium::setTileSize(const IntSize& size) m_tilingData.setMaxTextureSize(max(size.width(), size.height())); } +LayerTexture* LayerTilerChromium::getSingleTexture() +{ + Tile* tile = tileAt(0, 0); + return tile ? tile->texture() : 0; +} + void LayerTilerChromium::reset() { m_tiles.clear(); @@ -180,7 +190,7 @@ IntRect LayerTilerChromium::tileLayerRect(const Tile* tile) const void LayerTilerChromium::invalidateRect(const IntRect& contentRect) { - if (contentRect.isEmpty()) + if (contentRect.isEmpty() || m_skipsDraw) return; growLayerToContain(contentRect); @@ -236,6 +246,8 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont tile = createTile(i, j); if (!tile->texture()->isValid(m_tileSize, GraphicsContext3D::RGBA)) tile->m_dirtyLayerRect = tileLayerRect(tile); + else + tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA); dirtyLayerRect.unite(tile->m_dirtyLayerRect); } } @@ -243,27 +255,35 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont if (dirtyLayerRect.isEmpty()) return; - const IntRect paintRect = layerRectToContentRect(dirtyLayerRect); + m_paintRect = layerRectToContentRect(dirtyLayerRect); + + m_canvas.resize(m_paintRect.size()); - m_canvas.resize(paintRect.size()); - PlatformCanvas::Painter canvasPainter(&m_canvas); - canvasPainter.context()->translate(-paintRect.x(), -paintRect.y()); + // Assumption: if a tiler is using border texels, then it is because the + // layer is likely to be filtered or transformed. Because of it might be + // transformed, draw the text in grayscale instead of subpixel antialiasing. + PlatformCanvas::Painter::TextOption textOption = m_tilingData.borderTexels() ? PlatformCanvas::Painter::GrayscaleText : PlatformCanvas::Painter::SubpixelText; + PlatformCanvas::Painter canvasPainter(&m_canvas, textOption); + canvasPainter.context()->translate(-m_paintRect.x(), -m_paintRect.y()); { TRACE_EVENT("LayerTilerChromium::update::paint", this, 0); - painter.paint(*canvasPainter.context(), paintRect); + painter.paint(*canvasPainter.context(), m_paintRect); } +} +void LayerTilerChromium::uploadCanvas() +{ PlatformCanvas::AutoLocker locker(&m_canvas); { TRACE_EVENT("LayerTilerChromium::updateFromPixels", this, 0); - updateFromPixels(paintRect, locker.pixels()); + updateFromPixels(m_paintRect, locker.pixels()); } } void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels) { // Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update. - if (!m_tiles.size()) + if (!m_tilingData.totalSizeX() || !m_tilingData.totalSizeY()) return; GraphicsContext3D* context = layerRendererContext(); @@ -274,21 +294,26 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_ for (int i = left; i <= right; ++i) { Tile* tile = tileAt(i, j); if (!tile) - CRASH(); - if (!tile->dirty()) + tile = createTile(i, j); + else if (!tile->dirty()) continue; // Calculate page-space rectangle to copy from. IntRect sourceRect = tileContentRect(tile); const IntPoint anchor = sourceRect.location(); sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect)); + // Paint rect not guaranteed to line up on tile boundaries, so + // make sure that sourceRect doesn't extend outside of it. + sourceRect.intersect(paintRect); if (sourceRect.isEmpty()) continue; - if (!tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA)) { - m_skipsDraw = true; - reset(); - return; + if (!tile->texture()->isReserved()) { + if (!tile->texture()->reserve(m_tileSize, GraphicsContext3D::RGBA)) { + m_skipsDraw = true; + reset(); + return; + } } // Calculate tile-space rectangle to upload into. @@ -324,8 +349,10 @@ void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_ } tile->texture()->bindTexture(); - GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST)); - GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST)); + + const GC3Dint filter = m_tilingData.borderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST; + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, filter)); + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, filter)); GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource)); @@ -339,7 +366,7 @@ void LayerTilerChromium::setLayerPosition(const IntPoint& layerPosition) m_layerPosition = layerPosition; } -void LayerTilerChromium::draw(const IntRect& contentRect) +void LayerTilerChromium::draw(const IntRect& contentRect, const TransformationMatrix& globalTransform, float opacity) { if (m_skipsDraw || !m_tiles.size()) return; @@ -354,17 +381,18 @@ void LayerTilerChromium::draw(const IntRect& contentRect) for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { Tile* tile = tileAt(i, j); - ASSERT(tile); + if (!tile) + continue; tile->texture()->bindTexture(); - TransformationMatrix tileMatrix; + TransformationMatrix tileMatrix(globalTransform); // Don't use tileContentRect here, as that contains the full // rect with border texels which shouldn't be drawn. 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); + tileMatrix.translate3d(tileRect.x() + tileRect.width() / 2.0, tileRect.y() + tileRect.height() / 2.0, 0); IntPoint texOffset = m_tilingData.textureOffset(tile->i(), tile->j()); float tileWidth = static_cast<float>(m_tileSize.width()); @@ -374,13 +402,21 @@ void LayerTilerChromium::draw(const IntRect& contentRect) float texScaleX = tileRect.width() / tileWidth; float texScaleY = tileRect.height() / tileHeight; - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), 1, texTranslateX, texTranslateY, texScaleX, texScaleY, program); - - tile->texture()->unreserve(); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), opacity, texTranslateX, texTranslateY, texScaleX, texScaleY, program); } } } +void LayerTilerChromium::unreserveTextures() +{ + for (TileMap::iterator iter = m_tiles.begin(); iter != m_tiles.end(); ++iter) { + Tile* tile = iter->second.get(); + if (!tile) + continue; + tile->texture()->unreserve(); + } +} + void LayerTilerChromium::growLayerToContain(const IntRect& contentRect) { // Grow the tile array to contain this content rect. |