ContentLayerChromium.cpp [plain text]
#include "config.h"
#if USE(ACCELERATED_COMPOSITING)
#include "ContentLayerChromium.h"
#include "cc/CCLayerImpl.h"
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "LayerTexture.h"
#include "RenderLayerBacking.h"
#include "TextStream.h"
static int maxUntiledSize = 512;
static int defaultTileSize = 256;
using namespace std;
namespace WebCore {
PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner)
{
return adoptRef(new ContentLayerChromium(owner));
}
ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
: LayerChromium(owner)
, m_tilingOption(ContentLayerChromium::AutoTile)
{
}
ContentLayerChromium::~ContentLayerChromium()
{
m_tiler.clear();
LayerChromium::cleanupResources();
}
class ContentLayerPainter : public TilePaintInterface {
public:
explicit ContentLayerPainter(GraphicsLayerChromium* owner)
: m_owner(owner)
{
}
virtual void paint(GraphicsContext& context, const IntRect& contentRect)
{
context.clearRect(contentRect);
context.clip(contentRect);
m_owner->paintGraphicsLayerContents(context, contentRect);
}
private:
GraphicsLayerChromium* m_owner;
};
void ContentLayerChromium::paintContentsIfDirty(const IntRect& targetSurfaceRect)
{
ASSERT(drawsContent());
ASSERT(layerRenderer());
createTilerIfNeeded();
ContentLayerPainter painter(m_owner);
updateLayerSize(layerBounds().size());
IntRect layerRect = visibleLayerRect(targetSurfaceRect);
if (layerRect.isEmpty())
return;
IntRect dirty = enclosingIntRect(m_dirtyRect);
dirty.intersect(layerBounds());
m_tiler->invalidateRect(dirty);
m_tiler->update(painter, layerRect);
m_dirtyRect = FloatRect();
}
void ContentLayerChromium::setLayerRenderer(LayerRendererChromium* layerRenderer)
{
LayerChromium::setLayerRenderer(layerRenderer);
createTilerIfNeeded();
m_tiler->setLayerRenderer(layerRenderer);
}
TransformationMatrix ContentLayerChromium::tilingTransform()
{
TransformationMatrix transform = ccLayerImpl()->drawTransform();
IntSize size = bounds();
transform.translate(-size.width() / 2.0, -size.height() / 2.0);
return transform;
}
IntRect ContentLayerChromium::visibleLayerRect(const IntRect& targetSurfaceRect)
{
if (targetSurfaceRect.isEmpty())
return targetSurfaceRect;
const IntRect layerBoundRect = layerBounds();
const TransformationMatrix transform = tilingTransform();
IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
if (targetSurfaceRect.contains(layerInSurfaceSpace))
return layerBoundRect;
IntRect minimalSurfaceRect = targetSurfaceRect;
minimalSurfaceRect.intersect(layerInSurfaceSpace);
const TransformationMatrix surfaceToLayer = transform.inverse();
IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
layerRect.intersect(layerBoundRect);
return layerRect;
}
IntRect ContentLayerChromium::layerBounds() const
{
return IntRect(IntPoint(0, 0), bounds());
}
void ContentLayerChromium::updateLayerSize(const IntSize& layerSize)
{
if (!m_tiler)
return;
const IntSize tileSize(min(defaultTileSize, layerSize.width()), min(defaultTileSize, layerSize.height()));
const bool autoTiled = layerSize.width() > maxUntiledSize || layerSize.height() > maxUntiledSize;
bool isTiled;
if (m_tilingOption == AlwaysTile)
isTiled = true;
else if (m_tilingOption == NeverTile)
isTiled = false;
else
isTiled = autoTiled;
m_tiler->setTileSize(isTiled ? tileSize : layerSize);
}
void ContentLayerChromium::draw(const IntRect& targetSurfaceRect)
{
const TransformationMatrix transform = tilingTransform();
IntRect layerRect = visibleLayerRect(targetSurfaceRect);
if (!layerRect.isEmpty())
m_tiler->draw(layerRect, transform, ccLayerImpl()->drawOpacity());
}
void ContentLayerChromium::createTilerIfNeeded()
{
if (m_tiler)
return;
m_tiler = LayerTilerChromium::create(layerRenderer(), IntSize(defaultTileSize, defaultTileSize), LayerTilerChromium::HasBorderTexels);
}
void ContentLayerChromium::updateCompositorResources()
{
m_tiler->uploadCanvas();
}
void ContentLayerChromium::setTilingOption(TilingOption option)
{
m_tilingOption = option;
updateLayerSize(bounds());
}
void ContentLayerChromium::bindContentsTexture()
{
ASSERT(m_tilingOption == NeverTile);
ASSERT(m_tiler);
LayerTexture* texture = m_tiler->getSingleTexture();
ASSERT(texture);
texture->bindTexture();
}
void ContentLayerChromium::setIsMask(bool isMask)
{
setTilingOption(isMask ? NeverTile : AutoTile);
}
static void writeIndent(TextStream& ts, int indent)
{
for (int i = 0; i != indent; ++i)
ts << " ";
}
void ContentLayerChromium::dumpLayerProperties(TextStream& ts, int indent) const
{
LayerChromium::dumpLayerProperties(ts, indent);
writeIndent(ts, indent);
ts << "skipsDraw: " << (!m_tiler || m_tiler->skipsDraw()) << "\n";
}
}
#endif // USE(ACCELERATED_COMPOSITING)