#include "FloatRect.h"
#include "GraphicsContext.h"
#include "Image.h"
+#include "ImagesManager.h"
#include "Layer.h"
#include "Length.h"
#include "MediaLayer.h"
#include "ScaleTransformOperation.h"
#include "ScrollableLayerAndroid.h"
#include "SkCanvas.h"
+#include "SkRegion.h"
#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
static RenderLayer* renderLayerFromClient(GraphicsLayerClient* client)
{
- if (client)
- return static_cast<RenderLayerBacking*>(client)->owningLayer();
- return 0;
+ return client ? client->owningLayer() : 0;
}
GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_needsRepaint(false),
m_needsNotifyClient(false),
m_haveContents(false),
- m_haveImage(false),
m_newImage(false),
- m_imageRef(0),
+ m_image(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
{
RenderLayer* renderLayer = renderLayerFromClient(m_client);
m_contentLayer = new LayerAndroid(renderLayer);
+ m_dirtyRegion.setEmpty();
gDebugGraphicsLayerAndroidInstances++;
}
GraphicsLayerAndroid::~GraphicsLayerAndroid()
{
+ if (m_image)
+ m_image->deref();
+
m_contentLayer->unref();
SkSafeUnref(m_foregroundLayer);
SkSafeUnref(m_foregroundClipLayer);
void GraphicsLayerAndroid::updateFixedPosition()
{
- if (!m_client)
- return;
-
RenderLayer* renderLayer = renderLayerFromClient(m_client);
+ if (!renderLayer)
+ return;
RenderView* view = static_cast<RenderView*>(renderLayer->renderer());
if (!view)
// If it is a media layer the size may have changed as a result of the media
// element (e.g. plugin) gaining focus. Therefore, we must sync the size of
// the focus' outline so that our UI thread can draw accordingly.
- if (m_contentLayer->isMedia() && m_client) {
- RenderLayer* layer = renderLayerFromClient(m_client);
+ RenderLayer* layer = renderLayerFromClient(m_client);
+ if (layer && m_contentLayer->isMedia()) {
RenderBox* box = layer->renderBox();
int outline = box->view()->maximalOutlineSize();
static_cast<MediaLayer*>(m_contentLayer)->setOutlineSize(outline);
}
m_contentLayer->setSize(size.width(), size.height());
+ setNeedsDisplay();
askForSync();
}
void GraphicsLayerAndroid::setBackfaceVisibility(bool b)
{
+ if (b == m_backfaceVisibility)
+ return;
+
GraphicsLayer::setBackfaceVisibility(b);
m_contentLayer->setBackfaceVisibility(b);
askForSync();
if (drawsContent == m_drawsContent)
return;
GraphicsLayer::setDrawsContent(drawsContent);
+ m_contentLayer->setVisible(drawsContent);
if (m_drawsContent) {
m_haveContents = true;
setNeedsDisplay();
void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
{
- if (color == m_backgroundColor)
+ if (color == m_backgroundColor && m_backgroundColorSet)
return;
LOG("(%x) setBackgroundColor", this);
GraphicsLayer::setBackgroundColor(color);
void GraphicsLayerAndroid::clearBackgroundColor()
{
+ if (!m_backgroundColorSet)
+ return;
+
LOG("(%x) clearBackgroundColor", this);
GraphicsLayer::clearBackgroundColor();
askForSync();
m_foregroundClipLayer->setMasksToBounds(true);
m_foregroundClipLayer->addChild(m_foregroundLayer);
m_contentLayer->addChild(m_foregroundClipLayer);
+ m_contentLayer->setHasOverflowChildren(true);
} else {
ASSERT(iframeNeedsOverflow && !m_contentLayer->contentIsScrollable());
// No need to copy the children as they will be removed and synced.
LOG("(%x) repaint(), gPaused(%d) m_needsRepaint(%d) m_haveContents(%d) ",
this, gPaused, m_needsRepaint, m_haveContents);
- if (!gPaused && m_haveContents && m_needsRepaint && !m_haveImage) {
+ if (!gPaused && m_haveContents && m_needsRepaint && !m_image) {
// with SkPicture, we request the entire layer's content.
IntRect layerBounds(0, 0, m_size.width(), m_size.height());
RenderLayer* layer = renderLayerFromClient(m_client);
+ if (!layer)
+ return false;
if (m_foregroundLayer) {
PaintingPhase phase(this);
// Paint the background into a separate context.
phase.set(GraphicsLayerPaintBackground);
if (!paintContext(m_contentLayer->recordContext(), layerBounds))
return false;
+ m_contentLayer->checkTextPresence();
// Construct the foreground layer and draw.
RenderBox* box = layer->renderBox();
layer->scrollToOffset(0, 0);
// At this point, it doesn't matter if painting failed.
(void) paintContext(m_foregroundLayer->recordContext(), contentsRect);
+ m_foregroundLayer->checkTextPresence();
layer->scrollToOffset(scroll.width(), scroll.height());
// Construct the clip layer for masking the contents.
m_foregroundLayer->setPosition(-x, -y);
// Set the scrollable bounds of the layer.
m_foregroundLayer->setScrollLimits(-x, -y, m_size.width(), m_size.height());
+ m_foregroundLayer->markAsDirty(m_dirtyRegion);
m_foregroundLayer->needsRepaint();
} else {
// If there is no contents clip, we can draw everything into one
// picture.
if (!paintContext(m_contentLayer->recordContext(), layerBounds))
return false;
+ m_contentLayer->checkTextPresence();
// Check for a scrollable iframe and report the scrolling
// limits based on the view size.
if (m_contentLayer->contentIsScrollable()) {
m_contentLayer->getSize().width(),
m_contentLayer->getSize().height());
+ m_contentLayer->markAsDirty(m_dirtyRegion);
+ m_dirtyRegion.setEmpty();
m_contentLayer->needsRepaint();
m_needsRepaint = false;
- m_invalidatedRects.clear();
return true;
}
- if (m_needsRepaint && m_haveImage && m_newImage) {
+ if (m_needsRepaint && m_image && m_newImage) {
// We need to tell the GL thread that we will need to repaint the
// texture. Only do so if we effectively have a new image!
+ m_contentLayer->markAsDirty(m_dirtyRegion);
+ m_dirtyRegion.setEmpty();
m_contentLayer->needsRepaint();
m_newImage = false;
m_needsRepaint = false;
if (!canvas)
return false;
- PlatformGraphicsContext platformContext(canvas, 0);
+ PlatformGraphicsContext platformContext(canvas);
GraphicsContext graphicsContext(&platformContext);
paintGraphicsLayerContents(graphicsContext, rect);
void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
{
- for (unsigned int i = 0; i < m_children.size(); i++) {
- GraphicsLayer* layer = m_children[i];
- if (layer) {
- FloatRect childrenRect = m_transform.mapRect(rect);
- layer->setNeedsDisplayInRect(childrenRect);
- }
- }
+ // rect is in the render object coordinates
- if (!m_haveImage && !drawsContent()) {
+ if (!m_image && !drawsContent()) {
LOG("(%x) setNeedsDisplay(%.2f,%.2f,%.2f,%.2f) doesn't have content, bypass...",
this, rect.x(), rect.y(), rect.width(), rect.height());
return;
}
- bool addInval = true;
- const size_t maxDirtyRects = 8;
- for (size_t i = 0; i < m_invalidatedRects.size(); ++i) {
- if (m_invalidatedRects[i].contains(rect)) {
- addInval = false;
- break;
- }
- }
-
-#ifdef LAYER_DEBUG
- LOG("(%x) layer %d setNeedsDisplayInRect(%d) - (%.2f, %.2f, %.2f, %.2f)", this,
- m_contentLayer->uniqueId(), m_needsRepaint, rect.x(), rect.y(), rect.width(), rect.height());
-#endif
-
- if (addInval) {
- if (m_invalidatedRects.size() < maxDirtyRects)
- m_invalidatedRects.append(rect);
- else
- m_invalidatedRects[0].unite(rect);
- }
+ SkRegion region;
+ region.setRect(rect.x(), rect.y(),
+ rect.x() + rect.width(),
+ rect.y() + rect.height());
+ m_dirtyRegion.op(region, SkRegion::kUnion_Op);
m_needsRepaint = true;
askForSync();
void GraphicsLayerAndroid::setContentsToImage(Image* image)
{
TLOG("(%x) setContentsToImage", this, image);
- if (image) {
+ if (image && image != m_image) {
+ image->ref();
+ if (m_image)
+ m_image->deref();
+ m_image = image;
+
+ SkBitmapRef* bitmap = image->nativeImageForCurrentFrame();
+ m_contentLayer->setContentsImage(bitmap);
+
m_haveContents = true;
- m_haveImage = true;
- // Only pass the new image if it's a different one
- if (image->nativeImageForCurrentFrame() != m_imageRef) {
- m_newImage = true;
- m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
- // remember the passed image.
- m_imageRef = image->nativeImageForCurrentFrame();
- setNeedsDisplay();
- askForSync();
- }
+ m_newImage = true;
}
+ if (!image && m_image) {
+ m_contentLayer->setContentsImage(0);
+ m_image->deref();
+ m_image = 0;
+ }
+
+ setNeedsDisplay();
+ askForSync();
}
void GraphicsLayerAndroid::setContentsToMedia(PlatformLayer* mediaLayer)
mediaLayer->setPosition(m_contentLayer->getPosition().fX,
m_contentLayer->getPosition().fY);
mediaLayer->setSize(m_contentLayer->getWidth(), m_contentLayer->getHeight());
- mediaLayer->setDrawTransform(m_contentLayer->drawTransform());
+ mediaLayer->setDrawTransform(*m_contentLayer->drawTransform());
mediaLayer->ref();
m_contentLayer->unref();