TextureMapperTiledBackingStore.cpp [plain text]
#include "config.h"
#if USE(TEXTURE_MAPPER)
#include "TextureMapperTiledBackingStore.h"
#include "ImageBuffer.h"
#include "TextureMapper.h"
namespace WebCore {
class GraphicsLayer;
TextureMapperTiledBackingStore::TextureMapperTiledBackingStore()
{
}
void TextureMapperTiledBackingStore::updateContentsFromImageIfNeeded(TextureMapper* textureMapper)
{
if (!m_image)
return;
updateContents(textureMapper, m_image.get(), m_image->size(), enclosingIntRect(m_image->rect()), BitmapTexture::UpdateCannotModifyOriginalImageData);
m_image.clear();
}
TransformationMatrix TextureMapperTiledBackingStore::adjustedTransformForRect(const FloatRect& targetRect)
{
return TransformationMatrix::rectToRect(rect(), targetRect);
}
void TextureMapperTiledBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
{
updateContentsFromImageIfNeeded(textureMapper);
TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
for (size_t i = 0; i < m_tiles.size(); ++i)
m_tiles[i].paint(textureMapper, adjustedTransform, opacity, calculateExposedTileEdges(rect(), m_tiles[i].rect()));
}
void TextureMapperTiledBackingStore::drawBorder(TextureMapper* textureMapper, const Color& borderColor, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& transform)
{
TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
for (size_t i = 0; i < m_tiles.size(); ++i)
textureMapper->drawBorder(borderColor, borderWidth, m_tiles[i].rect(), adjustedTransform);
}
void TextureMapperTiledBackingStore::drawRepaintCounter(TextureMapper* textureMapper, int repaintCount, const Color& borderColor, const FloatRect& targetRect, const TransformationMatrix& transform)
{
TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
for (size_t i = 0; i < m_tiles.size(); ++i)
textureMapper->drawNumber(repaintCount, borderColor, m_tiles[i].rect().location(), adjustedTransform);
}
void TextureMapperTiledBackingStore::createOrDestroyTilesIfNeeded(const FloatSize& size, const IntSize& tileSize, bool hasAlpha)
{
if (size == m_size)
return;
m_size = size;
Vector<FloatRect> tileRectsToAdd;
Vector<int> tileIndicesToRemove;
static const size_t TileEraseThreshold = 6;
for (float y = 0; y < m_size.height(); y += tileSize.height()) {
for (float x = 0; x < m_size.width(); x += tileSize.width()) {
FloatRect tileRect(x, y, tileSize.width(), tileSize.height());
tileRect.intersect(rect());
tileRectsToAdd.append(tileRect);
}
}
for (int i = m_tiles.size() - 1; i >= 0; --i) {
FloatRect oldTile = m_tiles[i].rect();
bool existsAlready = false;
for (int j = tileRectsToAdd.size() - 1; j >= 0; --j) {
FloatRect newTile = tileRectsToAdd[j];
if (oldTile != newTile)
continue;
existsAlready = true;
tileRectsToAdd.remove(j);
break;
}
if (!existsAlready)
tileIndicesToRemove.append(i);
}
for (size_t i = 0; i < tileRectsToAdd.size(); ++i) {
if (!tileIndicesToRemove.isEmpty()) {
TextureMapperTile& tile = m_tiles[tileIndicesToRemove.last()];
tileIndicesToRemove.removeLast();
tile.setRect(tileRectsToAdd[i]);
if (tile.texture())
tile.texture()->reset(enclosingIntRect(tile.rect()).size(), hasAlpha ? BitmapTexture::SupportsAlpha : 0);
continue;
}
m_tiles.append(TextureMapperTile(tileRectsToAdd[i]));
}
for (size_t i = 0; i < tileIndicesToRemove.size() && m_tiles.size() > TileEraseThreshold; ++i)
m_tiles.remove(tileIndicesToRemove[i]);
}
void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper, Image* image, const FloatSize& totalSize, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag)
{
createOrDestroyTilesIfNeeded(totalSize, textureMapper->maxTextureSize(), !image->currentFrameKnownToBeOpaque());
for (size_t i = 0; i < m_tiles.size(); ++i)
m_tiles[i].updateContents(textureMapper, image, dirtyRect, updateContentsFlag);
}
void TextureMapperTiledBackingStore::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const FloatSize& totalSize, const IntRect& dirtyRect, BitmapTexture::UpdateContentsFlag updateContentsFlag)
{
createOrDestroyTilesIfNeeded(totalSize, textureMapper->maxTextureSize(), true);
for (size_t i = 0; i < m_tiles.size(); ++i)
m_tiles[i].updateContents(textureMapper, sourceLayer, dirtyRect, updateContentsFlag);
}
PassRefPtr<BitmapTexture> TextureMapperTiledBackingStore::texture() const
{
for (size_t i = 0; i < m_tiles.size(); ++i) {
RefPtr<BitmapTexture> texture = m_tiles[i].texture();
if (texture)
return texture;
}
return PassRefPtr<BitmapTexture>();
}
} #endif