summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp44
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.h1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp13
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp37
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h5
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp44
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp8
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp91
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h20
17 files changed, 221 insertions, 109 deletions
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index a6bf6af..3975545 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -531,8 +531,8 @@ void GraphicsLayerAndroid::updateScrollingLayers()
if (layerNeedsOverflow) {
ASSERT(!m_foregroundLayer && !m_foregroundClipLayer);
m_foregroundLayer = new ScrollableLayerAndroid(layer);
+ m_foregroundLayer->setIntrinsicallyComposited(true);
- // TODO: can clip layer be set to not intrinsically composited?
m_foregroundClipLayer = new LayerAndroid(layer);
m_foregroundClipLayer->setMasksToBounds(true);
m_foregroundClipLayer->addChild(m_foregroundLayer);
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index 62a5824..3241a61 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -79,8 +79,10 @@ void BaseLayerAndroid::updatePositionsRecursive(const SkRect& visibleContentRect
{
updateLayerPositions(visibleContentRect);
TransformationMatrix ident;
- FloatRect clip(0, 0, 1e10, 1e10);
- updateGLPositionsAndScale(ident, clip, 1, state()->scale());
+ FloatRect clip(0, 0, getWidth(), getHeight());
+
+ float scale = state() ? state()->scale() : 1.0f;
+ updateGLPositionsAndScale(ident, clip, 1, scale);
}
ForegroundBaseLayerAndroid::ForegroundBaseLayerAndroid(LayerContent* content)
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index feb2d99..7a25e7f 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -133,11 +133,13 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_replicatedLayerPosition = layer.m_replicatedLayerPosition;
+#ifdef ABSOLUTE_POSITION
// If we have absolute elements, we may need to reorder them if they
// are followed by another layer that is not also absolutely positioned.
// (as absolutely positioned elements are out of the normal flow)
bool hasAbsoluteChildren = false;
bool hasOnlyAbsoluteFollowers = true;
+
for (int i = 0; i < layer.countChildren(); i++) {
if (layer.getChild(i)->isPositionAbsolute()) {
hasAbsoluteChildren = true;
@@ -169,6 +171,10 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
for (int i = 0; i < layer.countChildren(); i++)
addChild(layer.getChild(i)->copy())->unref();
}
+#else
+ for (int i = 0; i < layer.countChildren(); i++)
+ addChild(layer.getChild(i)->copy())->unref();
+#endif
KeyframesMap::const_iterator end = layer.m_animations.end();
for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
@@ -572,9 +578,9 @@ void LayerAndroid::showLayer(int indent)
IntRect visible = visibleContentArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
- ALOGD("%s %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
+ ALOGD("%s s:%x %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d",
- spaces, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
+ spaces, m_surface, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
subclassType(), uniqueId(), this, m_owningLayer,
needsTexture() ? "needsTexture" : "",
m_imageCRC ? "hasImage" : "",
@@ -620,19 +626,8 @@ bool LayerAndroid::canJoinSurface(Surface* surface)
LayerAndroid* lastLayer = surface->getFirstLayer();
- // isolate non-tiled layers
- // TODO: remove this check so that multiple tiled layers with a invisible
- // one inbetween can be merged
- if (!needsTexture() || !lastLayer->needsTexture())
- return false;
-
- // isolate clipped layers
- // TODO: paint correctly with clip when merged
- if (m_haveClip || lastLayer->m_haveClip)
- return false;
-
// isolate intrinsically composited layers
- if (m_intrinsicallyComposited || lastLayer->m_intrinsicallyComposited)
+ if (needsIsolatedSurface() || lastLayer->needsIsolatedSurface())
return false;
// TODO: investigate potential for combining transformed layers
@@ -640,11 +635,6 @@ bool LayerAndroid::canJoinSurface(Surface* surface)
|| !lastLayer->m_drawTransform.isIdentityOrTranslation())
return false;
- // currently, we don't surface zoomable with non-zoomable layers (unless the
- // surface or the layer doesn't need a texture)
- if (surface->needsTexture() && needsTexture() && m_content->hasText() != surface->hasText())
- return false;
-
// TODO: compare other layer properties - fixed? overscroll? transformed?
return true;
#endif
@@ -664,24 +654,26 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
}
#ifdef LAYER_MERGING_DEBUG
- ALOGD("%*slayer %p(%d) rl %p %s surface %p, fixed %d, anim %d, intCom %d, haveClip %d scroll %d",
+ ALOGD("%*slayer %p(%d) rl %p %s surface %p lvl: %d, fixed %d, anim %d, intCom %d, haveClip %d scroll %d hasText (layer: %d surface: %d) hasContent %d size %.2f x %.2f",
4*mergeState->depth, "", this, m_uniqueId, m_owningLayer,
needNewSurface ? "NEW" : "joins", mergeState->currentSurface,
+ mergeState->nonMergeNestedLevel,
isPositionFixed(), m_animations.size() != 0,
m_intrinsicallyComposited,
m_haveClip,
- contentIsScrollable());
+ contentIsScrollable(), m_content ? m_content->hasText() : -1,
+ mergeState->currentSurface ? mergeState->currentSurface->hasText() : -1,
+ needsTexture(), getWidth(), getHeight());
#endif
mergeState->currentSurface->addLayer(this, m_drawTransform);
m_surface = mergeState->currentSurface;
- if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ if (contentIsScrollable() || isPositionFixed()) {
// disable layer merging within the children of these layer types
mergeState->nonMergeNestedLevel++;
}
-
// pass the surface through children in drawing order, so that they may
// attach themselves (and paint on it) if possible, or ignore it and create
// a new one if not
@@ -699,13 +691,17 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
mergeState->depth--;
}
- if (m_haveClip || contentIsScrollable() || isPositionFixed()) {
+ if (contentIsScrollable() || isPositionFixed()) {
// re-enable joining
mergeState->nonMergeNestedLevel--;
// disallow layers painting after to join with this surface
mergeState->currentSurface = 0;
}
+
+ if (needsIsolatedSurface())
+ mergeState->currentSurface = 0;
+
}
// We call this in WebViewCore, when copying the tree of layers.
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index c7c795f..52df0cf 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -281,6 +281,9 @@ public:
Surface* surface() { return m_surface; }
void setIntrinsicallyComposited(bool intCom) { m_intrinsicallyComposited = intCom; }
+ bool needsIsolatedSurface() {
+ return (needsTexture() && m_intrinsicallyComposited) || m_animations.size();
+ }
int setHwAccelerated(bool hwAccelerated);
diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
index 2819baa..6ff71d9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
@@ -198,11 +198,12 @@ const TransformationMatrix* ImageTexture::transform()
if (!m_layer)
return 0;
- IntRect layerArea = m_layer->fullContentArea();
- float scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width());
- float scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height());
TransformationMatrix d = *(m_layer->drawTransform());
TransformationMatrix m;
+ float scaleW = 1.0f;
+ float scaleH = 1.0f;
+ getImageToLayerScale(&scaleW, &scaleH);
+
m.scaleNonUniform(scaleW, scaleH);
m_layerMatrix = d.multiply(m);
return &m_layerMatrix;
@@ -228,6 +229,24 @@ bool ImageTexture::paint(SkCanvas* canvas)
return true;
}
+void ImageTexture::getImageToLayerScale(float* scaleW, float* scaleH) const
+{
+ if (!scaleW || !scaleH)
+ return;
+
+
+ IntRect layerArea = m_layer->fullContentArea();
+
+ if (layerArea.width() == 0 || layerArea.height() == 0)
+ return;
+
+ // calculate X, Y scale difference between image pixel coordinates and layer
+ // content coordinates
+
+ *scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width());
+ *scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height());
+}
+
void ImageTexture::drawGL(LayerAndroid* layer,
float opacity, FloatPoint* offset)
{
@@ -242,6 +261,16 @@ void ImageTexture::drawGL(LayerAndroid* layer,
if (m_tileGrid) {
bool force3dContentVisible = true;
IntRect visibleContentArea = m_layer->visibleContentArea(force3dContentVisible);
+
+ // transform visibleContentArea size to image size
+ float scaleW = 1.0f;
+ float scaleH = 1.0f;
+ getImageToLayerScale(&scaleW, &scaleH);
+ visibleContentArea.setX(visibleContentArea.x() / scaleW);
+ visibleContentArea.setWidth(visibleContentArea.width() / scaleW);
+ visibleContentArea.setY(visibleContentArea.y() / scaleH);
+ visibleContentArea.setHeight(visibleContentArea.height() / scaleH);
+
const TransformationMatrix* transformation = transform();
if (offset)
m_layerMatrix.translate(offset->x(), offset->y());
diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
index 0571b83..99bec90 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
@@ -95,6 +95,7 @@ public:
private:
const TransformationMatrix* transform();
+ void getImageToLayerScale(float* scaleW, float* scaleH) const;
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 2ec2659..7e4e918 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -226,19 +226,20 @@ void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit)
bool Surface::drawGL(bool layerTilesDisabled)
{
bool tilesDisabled = layerTilesDisabled && !isBase();
- if (!getFirstLayer()->visible())
+ if (singleLayer() && !getFirstLayer()->visible())
return false;
bool isBaseLayer = isBase()
|| getFirstLayer()->subclassType() == LayerAndroid::FixedBackgroundImageLayer
|| getFirstLayer()->subclassType() == LayerAndroid::ForegroundBaseLayer;
- if (!isBaseLayer) {
- // TODO: why are clipping regions wrong for base layer?
- FloatRect drawClip = getFirstLayer()->drawClip();
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
- TilesManager::instance()->shader()->clip(clippingRect);
+ FloatRect drawClip = getFirstLayer()->drawClip();
+ if (!singleLayer()) {
+ for (unsigned int i = 1; i < m_layers.size(); i++)
+ drawClip.unite(m_layers[i]->drawClip());
}
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
+ TilesManager::instance()->shader()->clip(clippingRect);
bool askRedraw = false;
if (m_surfaceBacking && !tilesDisabled) {
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.h b/Source/WebCore/platform/graphics/android/rendering/Surface.h
index a79a286..7100125 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.h
@@ -93,7 +93,7 @@ public:
LayerMergeState(Vector<Surface*>* const allGroups)
: surfaceList(allGroups)
, currentSurface(0)
- , nonMergeNestedLevel(-1) // start at -1 to ignore first LayerAndroid's clipping
+ , nonMergeNestedLevel(0)
, depth(0)
{}
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
index 558d720..f3415af 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -245,4 +245,14 @@ void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect)
#endif
}
+int SurfaceCollection::backedSize()
+{
+ int count = 0;
+ for (unsigned int i = 0; i < m_surfaces.size(); i++) {
+ if (m_surfaces[i]->needsTexture())
+ count++;
+ }
+ return count;
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
index 8debd6a..b502142 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -67,6 +67,9 @@ public:
bool hasCompositedAnimations();
void updateScrollableLayer(int layerId, int x, int y);
+ int size() { return m_surfaces.size(); }
+ int backedSize();
+
private:
void updateLayerPositions(const SkRect& visibleContentRect);
BaseLayerAndroid* m_compositedRoot;
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 8f2dcba..b4fd699 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -296,6 +296,12 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
GLUtils::clearBackgroundIfOpaque(&background);
}
+#ifdef DEBUG
+ ALOGV("Drawing %d / %d surfaces",
+ m_drawingCollection ? m_drawingCollection->backedSize() : -1,
+ m_drawingCollection ? m_drawingCollection->size() : -1);
+#endif
+
if (m_drawingCollection && m_drawingCollection->drawGL(visibleContentRect))
returnFlags |= DrawGlInfo::kStatusDraw;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index 41d6709..f273091 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -265,9 +265,9 @@ void TransferQueue::setHasGLContext(bool hasContext)
void TransferQueue::emptyAndAbandonQueue()
{
for (int i = 0 ; i < m_transferQueueSize; i++)
- m_transferQueue[i].status = emptyItem;
+ clearItemInTranferQueue(i);
m_emptyItemCount = m_transferQueueSize;
- m_pureColorTileQueue.clear();
+ clearPureColorQueue();
if (m_sharedSurfaceTexture.get()) {
m_sharedSurfaceTexture->abandon();
@@ -295,7 +295,7 @@ void TransferQueue::setPendingDiscard()
if (m_transferQueue[i].status == pendingBlit)
m_transferQueue[i].status = pendingDiscard;
- m_pureColorTileQueue.clear();
+ clearPureColorQueue();
bool GLContextExisted = getHasGLContext();
// Unblock the Tex Gen thread first before Tile Page deletion.
@@ -307,6 +307,15 @@ void TransferQueue::setPendingDiscard()
m_transferQueueItemCond.signal();
}
+void TransferQueue::clearPureColorQueue()
+{
+ for (unsigned int i = 0 ; i < m_pureColorTileQueue.size(); i++) {
+ SkSafeUnref(m_pureColorTileQueue[i].savedTilePainter);
+ m_pureColorTileQueue[i].savedTilePainter = 0;
+ }
+ m_pureColorTileQueue.clear();
+}
+
void TransferQueue::updatePureColorTiles()
{
for (unsigned int i = 0 ; i < m_pureColorTileQueue.size(); i++) {
@@ -324,7 +333,7 @@ void TransferQueue::updatePureColorTiles()
ALOGV("Warning: Don't expect an emptyItem here.");
}
}
- m_pureColorTileQueue.clear();
+ clearPureColorQueue();
}
// Call on UI thread to copy from the shared Surface Texture to the Tile's texture.
@@ -363,8 +372,7 @@ void TransferQueue::updateDirtyTiles()
if (result != OK)
ALOGE("unexpected error: updateTexImage return %d", result);
}
- m_transferQueue[index].savedTilePtr = 0;
- m_transferQueue[index].status = emptyItem;
+
if (obsoleteTile) {
ALOGV("Warning: the texture is obsolete for this baseTile");
index = (index + 1) % m_transferQueueSize;
@@ -391,7 +399,7 @@ void TransferQueue::updateDirtyTiles()
destTexture->setPure(false);
destTexture->transferComplete();
-
+ clearItemInTranferQueue(index);
ALOGV("Blit tile x, y %d %d with dest texture %p to destTexture->m_ownTextureId %d",
m_transferQueue[index].savedTilePtr,
destTexture,
@@ -469,6 +477,14 @@ void TransferQueue::addItemInPureColorQueue(const TileRenderInfo* renderInfo)
m_pureColorTileQueue.append(data);
}
+void TransferQueue::clearItemInTranferQueue(int index)
+{
+ m_transferQueue[index].savedTilePtr = 0;
+ SkSafeUnref(m_transferQueue[index].savedTilePainter);
+ m_transferQueue[index].savedTilePainter = 0;
+ m_transferQueue[index].status = emptyItem;
+}
+
// Translates the info from TileRenderInfo and others to TileTransferData.
// This is used by pure color tiles and normal tiles.
void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
@@ -476,6 +492,8 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
TileTransferData* data)
{
data->savedTileTexturePtr = renderInfo->baseTile->backTexture();
+ data->savedTilePainter = renderInfo->tilePainter;
+ SkSafeRef(data->savedTilePainter);
data->savedTilePtr = renderInfo->baseTile;
data->status = pendingBlit;
data->uploadType = type;
@@ -552,10 +570,7 @@ void TransferQueue::cleanupPendingDiscard()
tile->discardBackTexture();
ALOGV("transfer queue discarded tile %p, removed texture", tile);
}
-
- m_transferQueue[index].savedTilePtr = 0;
- m_transferQueue[index].savedTileTexturePtr = 0;
- m_transferQueue[index].status = emptyItem;
+ clearItemInTranferQueue(index);
}
index = (index + 1) % m_transferQueueSize;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index 44d3c37..9d33ff5 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -37,6 +37,7 @@
namespace WebCore {
class Tile;
+class TilePainter;
class TileTexture;
struct GLState {
@@ -75,6 +76,7 @@ public:
TileTransferData()
: status(emptyItem)
, savedTilePtr(0)
+ , savedTilePainter(0)
, savedTileTexturePtr(0)
, uploadType(DEFAULT_UPLOAD_TYPE)
, bitmap(0)
@@ -90,6 +92,7 @@ public:
TransferItemStatus status;
Tile* savedTilePtr;
+ TilePainter* savedTilePainter; // Ref count the tilePainter to keep the tile alive.
TileTexture* savedTileTexturePtr;
TextureUploadType uploadType;
// This is only useful in Cpu upload code path, so it will be dynamically
@@ -178,10 +181,12 @@ private:
GLuint srcTexId, GLenum srcTexTarget,
int index);
+ void clearItemInTranferQueue(int index);
void addItemCommon(const TileRenderInfo* renderInfo,
TextureUploadType type, TileTransferData* data);
void updatePureColorTiles();
+ void clearPureColorQueue();
// Note that the m_transferQueueIndex only changed in the TexGen thread
// where we are going to move on to update the next item in the queue.
int m_transferQueueIndex;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 7d70533..f5dddc0 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -302,6 +302,7 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
bool layersChanged = false;
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ compState.m_positionedSibling = false;
compState.m_hasFixedElement = false;
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -657,27 +658,25 @@ bool RenderLayerCompositor::checkForPositionedElements(Vector<RenderLayer*>* lis
// composited. The layers' surfaces will be merged if needed UI-side.
for (int j = 0; j < listSize; ++j) {
RenderLayer* currentLayer = list->at(j);
- if (currentLayer->shouldComposite())
- continue;
- if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
- haveFixedLayer = j;
- fixedSibling = true;
- }
+ // clear the composited flag first
+ currentLayer->setShouldComposite(false);
- // Bypass fixed layers with a width or height or 1 or less...
- IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
- FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
- if ((currentLayerBounds.width() <= 1
- || currentLayerBounds.height() <= 1)
- && haveFixedLayer == j) {
- haveFixedLayer = -1;
- fixedSibling = false;
+ if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
+ // Ignore fixed layers with a width or height or 1 or less...
+ IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
+ FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
+ if (currentLayerBounds.width() > 1 && currentLayerBounds.height() > 1) {
+ haveFixedLayer = j;
+ fixedSibling = true;
+ }
+ continue;
}
- if (haveFixedLayer != -1 && haveFixedLayer != j)
+ if (haveFixedLayer != -1)
currentLayer->setShouldComposite(true);
}
+
return positionedSibling || fixedSibling;
}
@@ -867,6 +866,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
if (childState.m_hasFixedElement)
compositingState.m_hasFixedElement = true;
+ if (childState.m_positionedSibling)
+ compositingState.m_positionedSibling = true;
#endif
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
if (childState.m_hasScrollableElement)
@@ -889,7 +890,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
// We also need to check that we don't have a scrollable layer, as this
// would not have set the m_subtreeIsCompositing flag
- if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !childState.m_hasFixedElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing
+ && !childState.m_hasScrollableElement && !childState.m_positionedSibling && !childState.m_hasFixedElement
+ && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
#else
if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
#endif
@@ -1425,13 +1428,8 @@ bool RenderLayerCompositor::requiresCompositingForAndroidLayers(const RenderLaye
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
// Enable composited layers (for fixed elements)
- if (layer->isFixed()) {
- // Skip fixed layers with a width or height of 1 or less...
- IntRect bounds = layer->renderer()->localToAbsoluteQuad(
- FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
- if (bounds.width() > 1 && bounds.height() > 1)
- return true;
- }
+ if (layer->isFixed())
+ return true;
#endif
if (layer->renderer()->isCanvas())
diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp
index f3e46ac..ccdfa59 100644
--- a/Source/WebKit/android/jni/PicturePile.cpp
+++ b/Source/WebKit/android/jni/PicturePile.cpp
@@ -144,9 +144,11 @@ void PicturePile::setSize(const IntSize& size)
// TODO: See above about just adding invals for new content
m_pile.clear();
m_webkitInvals.clear();
- IntRect area(0, 0, size.width(), size.height());
- m_webkitInvals.append(area);
- m_pile.append(area);
+ if (!size.isEmpty()) {
+ IntRect area(0, 0, size.width(), size.height());
+ m_webkitInvals.append(area);
+ m_pile.append(area);
+ }
}
void PicturePile::updatePicturesIfNeeded(PicturePainter* painter)
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index af76daa..8870b70 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -617,7 +617,7 @@ WebCore::Node* WebViewCore::currentFocus()
return focusedFrame()->document()->focusedNode();
}
-void WebViewCore::recordPicturePile()
+void WebViewCore::layout()
{
TRACE_METHOD();
@@ -631,9 +631,7 @@ void WebViewCore::recordPicturePile()
// it's fine for layout to gather invalidates, but defeat sending a message
// back to java to call webkitDraw, since we're already in the middle of
// doing that
- m_skipContentDraw = true;
bool success = layoutIfNeededRecursive(m_mainFrame);
- m_skipContentDraw = false;
// We may be mid-layout and thus cannot draw.
if (!success)
@@ -699,16 +697,16 @@ void WebViewCore::recordPicturePile()
view->forceLayout();
// Relayout similar to above
- m_skipContentDraw = true;
- bool success = layoutIfNeededRecursive(m_mainFrame);
- m_skipContentDraw = false;
- if (!success)
- return;
-
- // Set the computed content width
- width = view->contentsWidth();
- height = view->contentsHeight();
+ layoutIfNeededRecursive(m_mainFrame);
}
+}
+
+void WebViewCore::recordPicturePile()
+{
+ // if the webkit page dimensions changed, discard the pictureset and redraw.
+ WebCore::FrameView* view = m_mainFrame->view();
+ int width = view ? view->contentsWidth() : 0;
+ int height = view ? view->contentsHeight() : 0;
m_content.setSize(IntSize(width, height));
@@ -732,6 +730,11 @@ bool WebViewCore::focusBoundsChanged()
void WebViewCore::paintContents(WebCore::GraphicsContext* gc, WebCore::IntRect& dirty)
{
WebCore::FrameView* view = m_mainFrame->view();
+ if (!view) {
+ gc->setFillColor(WebCore::Color::white, WebCore::ColorSpaceDeviceRGB);
+ gc->fillColor();
+ return;
+ }
IntPoint origin = view->minimumScrollPosition();
IntRect drawArea = dirty;
@@ -813,7 +816,7 @@ void WebViewCore::notifyAnimationStarted()
}
-BaseLayerAndroid* WebViewCore::createBaseLayer()
+BaseLayerAndroid* WebViewCore::createBaseLayer(GraphicsLayerAndroid* root)
{
// We set the background color
Color background = Color::white;
@@ -878,15 +881,7 @@ BaseLayerAndroid* WebViewCore::createBaseLayer()
SkSafeUnref(content);
- m_skipContentDraw = true;
- bool layoutSucceeded = layoutIfNeededRecursive(m_mainFrame);
- m_skipContentDraw = false;
- // Layout only fails if called during a layout.
- ALOG_ASSERT(layoutSucceeded, "Can never be called recursively");
-
// We update the layers
- ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
- GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync());
if (root) {
LayerAndroid* copyLayer = new LayerAndroid(*root->contentLayer());
base->addChild(copyLayer);
@@ -899,9 +894,14 @@ BaseLayerAndroid* WebViewCore::createBaseLayer()
BaseLayerAndroid* WebViewCore::recordContent(SkIPoint* point)
{
+ m_skipContentDraw = true;
+ layout();
+ ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
+ GraphicsLayerAndroid* root = static_cast<GraphicsLayerAndroid*>(chromeC->layersSync());
+ m_skipContentDraw = false;
recordPicturePile();
- BaseLayerAndroid* baseLayer = createBaseLayer();
+ BaseLayerAndroid* baseLayer = createBaseLayer(root);
baseLayer->markAsDirty(m_content.dirtyRegion());
m_content.dirtyRegion().setEmpty();
@@ -1686,6 +1686,35 @@ IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point,
return IntPoint(point.x() + frameOffset.x(), point.y() + frameOffset.y());
}
+Position WebViewCore::trimSelectionPosition(const Position &start, const Position& stop)
+{
+ int direction = comparePositions(start, stop);
+ if (direction == 0)
+ return start;
+ bool forward = direction < 0;
+ EAffinity affinity = forward ? DOWNSTREAM : UPSTREAM;
+ bool move;
+ Position pos = start;
+ bool movedTooFar = false;
+ do {
+ move = true;
+ Node* node = pos.anchorNode();
+ if (node && node->isTextNode() && node->renderer()) {
+ RenderText *textRenderer = toRenderText(node->renderer());
+ move = !textRenderer->textLength();
+ }
+ if (move) {
+ Position nextPos = forward ? pos.next() : pos.previous();
+ movedTooFar = nextPos.isNull() || pos == nextPos
+ || ((comparePositions(nextPos, stop) < 0) != forward);
+ pos = nextPos;
+ }
+ } while (move && !movedTooFar);
+ if (movedTooFar)
+ pos = stop;
+ return pos;
+}
+
void WebViewCore::selectText(int startX, int startY, int endX, int endY)
{
SelectionController* sc = focusedFrame()->selection();
@@ -1722,7 +1751,11 @@ void WebViewCore::selectText(int startX, int startY, int endX, int endY)
endPosition = prevEndPosition;
}
- VisibleSelection selection(startPosition, endPosition);
+ Position start = startPosition.deepEquivalent();
+ Position end = endPosition.deepEquivalent();
+ start = trimSelectionPosition(start, end);
+ end = trimSelectionPosition(end, start);
+ VisibleSelection selection(start, end);
// Only allow changes between caret positions or to text selection.
bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret());
if (selectChangeAllowed && sc->shouldChangeSelection(selection))
@@ -1750,7 +1783,7 @@ bool WebViewCore::nodeIsClickableOrFocusable(Node* node)
AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool doMoveMouse)
{
if (doMoveMouse)
- moveMouse(x, y);
+ moveMouse(x, y, 0, true);
HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y),
false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop));
AndroidHitTestResult androidHitResult(this, hitTestResult);
@@ -1909,7 +1942,7 @@ AndroidHitTestResult WebViewCore::hitTestAtPoint(int x, int y, int slop, bool do
testRect.move(frameAdjust.x(), frameAdjust.y());
testRect.intersect(rect);
if (!testRect.contains(x, y))
- moveMouse(testRect.center().x(), testRect.center().y());
+ moveMouse(testRect.center().x(), testRect.center().y(), 0, true);
}
} else {
androidHitResult.searchContentDetectors();
@@ -2088,10 +2121,12 @@ static PluginView* nodeIsPlugin(Node* node) {
///////////////////////////////////////////////////////////////////////////////
// Update mouse position
-void WebViewCore::moveMouse(int x, int y, HitTestResult* hoveredNode)
+void WebViewCore::moveMouse(int x, int y, HitTestResult* hoveredNode, bool isClickCandidate)
{
// mouse event expects the position in the window coordinate
m_mousePos = WebCore::IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY);
+ if (isClickCandidate)
+ m_mouseClickPos = m_mousePos;
// validNode will still return true if the node is null, as long as we have
// a valid frame. Do not want to make a call on frame unless it is valid.
WebCore::PlatformMouseEvent mouseEvent(m_mousePos, m_mousePos,
@@ -3207,12 +3242,12 @@ bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint
bool WebViewCore::performMouseClick()
{
- WebCore::PlatformMouseEvent mouseDown(m_mousePos, m_mousePos, WebCore::LeftButton,
+ WebCore::PlatformMouseEvent mouseDown(m_mouseClickPos, m_mouseClickPos, WebCore::LeftButton,
WebCore::MouseEventPressed, 1, false, false, false, false,
WTF::currentTime());
// ignore the return from as it will return true if the hit point can trigger selection change
m_mainFrame->eventHandler()->handleMousePressEvent(mouseDown);
- WebCore::PlatformMouseEvent mouseUp(m_mousePos, m_mousePos, WebCore::LeftButton,
+ WebCore::PlatformMouseEvent mouseUp(m_mouseClickPos, m_mouseClickPos, WebCore::LeftButton,
WebCore::MouseEventReleased, 1, false, false, false, false,
WTF::currentTime());
bool handled = m_mainFrame->eventHandler()->handleMouseReleaseEvent(mouseUp);
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index a3c1e7c..bfd9387 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -161,11 +161,6 @@ namespace android {
*/
void contentDraw();
- /**
- * copy the layers to the UI side
- */
- void layersDraw();
-
#if USE(ACCELERATED_COMPOSITING)
WebCore::GraphicsLayerAndroid* graphicsRootLayer() const;
#endif
@@ -304,7 +299,8 @@ namespace android {
// scroll the selection on screen (if necessary).
void revealSelection();
- void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0);
+ void moveMouse(int x, int y, WebCore::HitTestResult* hoveredNode = 0,
+ bool isClickCandidate = false);
// set the scroll amount that webview.java is currently showing
void setScrollOffset(bool sendScrollEvent, int dx, int dy);
@@ -517,7 +513,7 @@ namespace android {
// This creates a new BaseLayerAndroid by copying the current m_content
// and doing a copy of the layers. The layers' content may be updated
// as we are calling layersSync().
- WebCore::BaseLayerAndroid* createBaseLayer();
+ WebCore::BaseLayerAndroid* createBaseLayer(GraphicsLayerAndroid* root);
bool updateLayers(WebCore::LayerAndroid*);
void notifyAnimationStarted();
@@ -618,6 +614,7 @@ namespace android {
};
WebCore::Node* currentFocus();
+ void layout();
// Create a set of pictures to represent the drawn DOM, driven by
// the invalidated region and the time required to draw (used to draw)
void recordPicturePile();
@@ -738,6 +735,8 @@ namespace android {
static WebCore::IntRect positionToTextRect(const WebCore::Position& position,
WebCore::EAffinity affinity);
static bool isLtr(const WebCore::Position& position);
+ static WebCore::Position trimSelectionPosition(
+ const WebCore::Position& start, const WebCore::Position& stop);
// called from constructor, to add this to a global list
static void addInstance(WebViewCore*);
@@ -768,6 +767,13 @@ namespace android {
int m_scrollOffsetY; // webview.java's current scroll in Y
double m_scrollSetTime; // when the scroll was last set
WebCore::IntPoint m_mousePos;
+ // This is the location at which we will click. This is tracked
+ // separately from m_mousePos, because m_mousePos may be updated
+ // in the interval between ACTION_UP and when the click fires since
+ // that occurs after a delay. This also works around potential hardware
+ // issues if we get onHoverEvents when using the touch screen, as that
+ // will nullify the slop checking we do in hitTest (aka, ACTION_DOWN)
+ WebCore::IntPoint m_mouseClickPos;
int m_screenWidth; // width of the visible rect in document coordinates
int m_screenHeight;// height of the visible rect in document coordinates
int m_textWrapWidth;