diff options
Diffstat (limited to 'cc/ImageLayerChromium.cpp')
-rw-r--r-- | cc/ImageLayerChromium.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/cc/ImageLayerChromium.cpp b/cc/ImageLayerChromium.cpp new file mode 100644 index 0000000..09c97d8 --- /dev/null +++ b/cc/ImageLayerChromium.cpp @@ -0,0 +1,161 @@ +// Copyright 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "ImageLayerChromium.h" + +#include "CCLayerTreeHost.h" +#include "LayerTextureUpdater.h" +#include "PlatformColor.h" + +namespace WebCore { + +class ImageLayerTextureUpdater : public LayerTextureUpdater { +public: + class Texture : public LayerTextureUpdater::Texture { + public: + Texture(ImageLayerTextureUpdater* textureUpdater, PassOwnPtr<CCPrioritizedTexture> texture) + : LayerTextureUpdater::Texture(texture) + , m_textureUpdater(textureUpdater) + { + } + + virtual void updateRect(CCResourceProvider* resourceProvider, const IntRect& sourceRect, const IntSize& destOffset) OVERRIDE + { + textureUpdater()->updateTextureRect(resourceProvider, texture(), sourceRect, destOffset); + } + + private: + ImageLayerTextureUpdater* textureUpdater() { return m_textureUpdater; } + + ImageLayerTextureUpdater* m_textureUpdater; + }; + + static PassRefPtr<ImageLayerTextureUpdater> create() + { + return adoptRef(new ImageLayerTextureUpdater()); + } + + virtual ~ImageLayerTextureUpdater() { } + + virtual PassOwnPtr<LayerTextureUpdater::Texture> createTexture(CCPrioritizedTextureManager* manager) + { + return adoptPtr(new Texture(this, CCPrioritizedTexture::create(manager))); + } + + virtual SampledTexelFormat sampledTexelFormat(GC3Denum textureFormat) OVERRIDE + { + return PlatformColor::sameComponentOrder(textureFormat) ? + LayerTextureUpdater::SampledTexelFormatRGBA : LayerTextureUpdater::SampledTexelFormatBGRA; + } + + void updateTextureRect(CCResourceProvider* resourceProvider, CCPrioritizedTexture* texture, const IntRect& sourceRect, const IntSize& destOffset) + { + // Source rect should never go outside the image pixels, even if this + // is requested because the texture extends outside the image. + IntRect clippedSourceRect = sourceRect; + IntRect imageRect = IntRect(0, 0, m_bitmap.width(), m_bitmap.height()); + clippedSourceRect.intersect(imageRect); + + IntSize clippedDestOffset = destOffset + IntSize(clippedSourceRect.location() - sourceRect.location()); + + SkAutoLockPixels lock(m_bitmap); + texture->upload(resourceProvider, static_cast<const uint8_t*>(m_bitmap.getPixels()), imageRect, clippedSourceRect, clippedDestOffset); + } + + void setBitmap(const SkBitmap& bitmap) + { + m_bitmap = bitmap; + } + +private: + ImageLayerTextureUpdater() { } + + SkBitmap m_bitmap; +}; + +PassRefPtr<ImageLayerChromium> ImageLayerChromium::create() +{ + return adoptRef(new ImageLayerChromium()); +} + +ImageLayerChromium::ImageLayerChromium() + : TiledLayerChromium() +{ +} + +ImageLayerChromium::~ImageLayerChromium() +{ +} + +void ImageLayerChromium::setBitmap(const SkBitmap& bitmap) +{ + // setBitmap() currently gets called whenever there is any + // style change that affects the layer even if that change doesn't + // affect the actual contents of the image (e.g. a CSS animation). + // With this check in place we avoid unecessary texture uploads. + if (bitmap.pixelRef() && bitmap.pixelRef() == m_bitmap.pixelRef()) + return; + + m_bitmap = bitmap; + setNeedsDisplay(); +} + +void ImageLayerChromium::setTexturePriorities(const CCPriorityCalculator& priorityCalc) +{ + // Update the tile data before creating all the layer's tiles. + updateTileSizeAndTilingOption(); + + TiledLayerChromium::setTexturePriorities(priorityCalc); +} + +void ImageLayerChromium::update(CCTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStats& stats) +{ + createTextureUpdaterIfNeeded(); + if (m_needsDisplay) { + m_textureUpdater->setBitmap(m_bitmap); + updateTileSizeAndTilingOption(); + invalidateContentRect(IntRect(IntPoint(), contentBounds())); + m_needsDisplay = false; + } + TiledLayerChromium::update(queue, occlusion, stats); +} + +void ImageLayerChromium::createTextureUpdaterIfNeeded() +{ + if (m_textureUpdater) + return; + + m_textureUpdater = ImageLayerTextureUpdater::create(); + GC3Denum textureFormat = layerTreeHost()->rendererCapabilities().bestTextureFormat; + setTextureFormat(textureFormat); + setSampledTexelFormat(textureUpdater()->sampledTexelFormat(textureFormat)); +} + +LayerTextureUpdater* ImageLayerChromium::textureUpdater() const +{ + return m_textureUpdater.get(); +} + +IntSize ImageLayerChromium::contentBounds() const +{ + return IntSize(m_bitmap.width(), m_bitmap.height()); +} + +bool ImageLayerChromium::drawsContent() const +{ + return !m_bitmap.isNull() && TiledLayerChromium::drawsContent(); +} + +bool ImageLayerChromium::needsContentsScale() const +{ + // Contents scale is not need for image layer because this can be done in compositor more efficiently. + return false; +} + +} +#endif // USE(ACCELERATED_COMPOSITING) |