summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp2
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h5
-rw-r--r--Source/WebCore/loader/cache/CachedResource.cpp2
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h1
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp30
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp66
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.h15
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/ClassTracker.cpp21
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/GLUtils.h1
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp33
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h5
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp45
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.cpp214
-rw-r--r--Source/WebCore/platform/graphics/android/ImageTexture.h69
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.cpp108
-rw-r--r--Source/WebCore/platform/graphics/android/ImagesManager.h16
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp111
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h13
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.cpp12
-rw-r--r--Source/WebCore/platform/graphics/android/PaintTileOperation.h8
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.cpp13
-rw-r--r--Source/WebCore/platform/graphics/android/PaintedSurface.h4
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.cpp58
-rw-r--r--Source/WebCore/platform/graphics/android/ShaderProgram.h30
-rw-r--r--Source/WebCore/platform/graphics/android/TexturesGenerator.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/TilePainter.h10
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp31
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.cpp30
-rw-r--r--Source/WebCore/platform/graphics/android/TiledTexture.h10
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp17
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h2
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.cpp76
-rw-r--r--Source/WebCore/platform/graphics/android/TreeManager.h12
-rw-r--r--Source/WebCore/rendering/RenderBlockLineLayout.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp7
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp7
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp5
44 files changed, 764 insertions, 362 deletions
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index ba30860..6867302 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -57,6 +57,7 @@ CachedImage::CachedImage(const String& url)
, m_image(0)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
+ , m_autoLoadWasPreventedBySettings(false)
{
setStatus(Unknown);
}
@@ -66,6 +67,7 @@ CachedImage::CachedImage(Image* image)
, m_image(image)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
+ , m_autoLoadWasPreventedBySettings(false)
{
setStatus(Cached);
setLoading(false);
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 42c7814..79643d7 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -75,7 +75,7 @@ public:
void clear();
- bool stillNeedsLoad() const { return !errorOccurred() && status() == Unknown && !isLoading(); }
+ bool stillNeedsLoad() const { return (!errorOccurred() && status() == Unknown && !isLoading()) || (m_autoLoadWasPreventedBySettings && !inCache()); }
void load();
// ImageObserver
@@ -86,6 +86,8 @@ public:
virtual void animationAdvanced(const Image*);
virtual void changedInRect(const Image*, const IntRect&);
+ void setAutoLoadWasPreventedBySettings(bool prevented) { m_autoLoadWasPreventedBySettings = prevented; }
+
private:
void createImage();
size_t maximumDecodedImageSize();
@@ -98,6 +100,7 @@ private:
RefPtr<Image> m_image;
Timer<CachedImage> m_decodedDataDeletionTimer;
bool m_shouldPaintBrokenImage;
+ bool m_autoLoadWasPreventedBySettings;
};
}
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index 95f5522..e599769 100644
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -261,7 +261,7 @@ void CachedResource::addClient(CachedResourceClient* client)
void CachedResource::didAddClient(CachedResourceClient* c)
{
- if (!isLoading())
+ if (!isLoading() && !stillNeedsLoad())
c->notifyFinished(this);
}
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index 72b00e5..2f33ac7 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -127,6 +127,7 @@ public:
bool isLoading() const { return m_loading; }
void setLoading(bool b) { m_loading = b; }
+ virtual bool stillNeedsLoad() const { return false; }
virtual bool isImage() const { return false; }
bool isLinkResource() const
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 38fcee4..91c0629 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -138,14 +138,21 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
}
}
CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, url, String()));
- if (autoLoadImages() && resource && resource->stillNeedsLoad()) {
+ if (resource) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (shouldBlockNetworkImage(url)) {
- return resource;
- }
+ resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(url));
+#else
+ resource->setAutoLoadWasPreventedBySettings(!autoLoadImages());
+#endif
+ if (autoLoadImages() && resource->stillNeedsLoad()) {
+#ifdef ANDROID_BLOCK_NETWORK_IMAGE
+ if (shouldBlockNetworkImage(url)) {
+ return resource;
+ }
#endif
- resource->setLoading(true);
- load(resource, true);
+ resource->setLoading(true);
+ load(resource, true);
+ }
}
return resource;
}
@@ -520,9 +527,12 @@ void CachedResourceLoader::setAutoLoadImages(bool enable)
if (shouldBlockNetworkImage(image->url()))
continue;
#endif
+ image->setAutoLoadWasPreventedBySettings(false);
- if (image->stillNeedsLoad())
+ if (image->stillNeedsLoad()) {
+ image->setLoading(true);
load(image, true);
+ }
}
}
}
@@ -536,7 +546,6 @@ bool CachedResourceLoader::shouldBlockNetworkImage(const String& url) const
KURL kurl = m_document->completeURL(url);
if (kurl.protocolIs("http") || kurl.protocolIs("https"))
return true;
-
return false;
}
@@ -555,8 +564,11 @@ void CachedResourceLoader::setBlockNetworkImage(bool block)
CachedResource* resource = it->second.get();
if (resource->type() == CachedResource::ImageResource) {
CachedImage* image = const_cast<CachedImage*>(static_cast<const CachedImage*>(resource));
- if (image->stillNeedsLoad())
+ image->setAutoLoadWasPreventedBySettings(false);
+ if (image->stillNeedsLoad()) {
+ image->setLoading(true);
load(image, true);
+ }
}
}
}
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
index 5601269..6b22359 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -49,6 +49,8 @@
namespace WebCore {
+static int gUniqueId;
+
static long gDebugAndroidAnimationInstances;
long AndroidAnimation::instancesCount()
@@ -69,27 +71,11 @@ AndroidAnimation::AndroidAnimation(AnimatedPropertyID type,
, m_timingFunction(animation->timingFunction())
, m_type(type)
, m_operations(operations)
+ , m_uniqueId(++gUniqueId)
+ , m_hasFinished(false)
{
ASSERT(m_timingFunction);
- if (!static_cast<int>(beginTime)) // time not set
- m_beginTime = WTF::currentTime();
-
- gDebugAndroidAnimationInstances++;
-}
-
-AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
- : m_beginTime(anim->m_beginTime)
- , m_duration(anim->m_duration)
- , m_fillsBackwards(anim->m_fillsBackwards)
- , m_fillsForwards(anim->m_fillsForwards)
- , m_iterationCount(anim->m_iterationCount)
- , m_direction(anim->m_direction)
- , m_timingFunction(anim->m_timingFunction)
- , m_name(anim->name())
- , m_type(anim->m_type)
- , m_operations(anim->m_operations)
-{
gDebugAndroidAnimationInstances++;
}
@@ -98,20 +84,23 @@ AndroidAnimation::~AndroidAnimation()
gDebugAndroidAnimationInstances--;
}
-double AndroidAnimation::elapsedTime(double time)
+void AndroidAnimation::suggestBeginTime(double time)
{
- if (m_beginTime <= 0.000001) // overflow or not correctly set
+ if (m_beginTime <= 0.000001) // overflow or not yet set
m_beginTime = time;
+}
- m_elapsedTime = time - m_beginTime;
+double AndroidAnimation::elapsedTime(double time)
+{
+ double elapsedTime = (m_beginTime < 0.000001) ? 0 : time - m_beginTime;
if (m_duration <= 0)
m_duration = 0.000001;
- if (m_elapsedTime < 0) // animation not yet started.
+ if (elapsedTime < 0) // animation not yet started.
return 0;
- return m_elapsedTime;
+ return elapsedTime;
}
bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgress)
@@ -127,6 +116,13 @@ bool AndroidAnimation::checkIterationsAndProgress(double time, float* finalProgr
// If not infinite, return false if we are done
if (m_iterationCount > 0 && progress > dur) {
*finalProgress = 1.0;
+ if (!m_hasFinished) {
+ // first time past duration, continue with progress 1.0 so the
+ // element's final position lines up with it's last keyframe
+ m_hasFinished = true;
+ return true;
+ }
+
return false;
}
@@ -187,7 +183,7 @@ bool AndroidAnimation::evaluate(LayerAndroid* layer, double time)
if (progress < 0) {
// The animation hasn't started yet
- if (m_fillsBackwards) {
+ if (m_fillsBackwards || m_beginTime <= 0.000001) {
// in this case we want to apply the initial keyframe to the layer
applyForProgress(layer, 0);
}
@@ -195,7 +191,7 @@ bool AndroidAnimation::evaluate(LayerAndroid* layer, double time)
return true;
}
- if (progress >= 1) {
+ if (progress > 1) {
if (!m_fillsForwards)
return false;
progress = 1;
@@ -225,16 +221,6 @@ AndroidOpacityAnimation::AndroidOpacityAnimation(const Animation* animation,
{
}
-AndroidOpacityAnimation::AndroidOpacityAnimation(AndroidOpacityAnimation* anim)
- : AndroidAnimation(anim)
-{
-}
-
-PassRefPtr<AndroidAnimation> AndroidOpacityAnimation::copy()
-{
- return adoptRef(new AndroidOpacityAnimation(this));
-}
-
void AndroidAnimation::pickValues(double progress, int* start, int* end)
{
float distance = -1;
@@ -298,16 +284,6 @@ AndroidTransformAnimation::AndroidTransformAnimation(const Animation* animation,
{
}
-AndroidTransformAnimation::AndroidTransformAnimation(AndroidTransformAnimation* anim)
- : AndroidAnimation(anim)
-{
-}
-
-PassRefPtr<AndroidAnimation> AndroidTransformAnimation::copy()
-{
- return adoptRef(new AndroidTransformAnimation(this));
-}
-
void AndroidTransformAnimation::applyForProgress(LayerAndroid* layer, float progress)
{
// First, we need to get the from and to values
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.h b/Source/WebCore/platform/graphics/android/AndroidAnimation.h
index 16a63e8..dca769f 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.h
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.h
@@ -33,16 +33,15 @@ namespace WebCore {
class TimingFunction;
-class AndroidAnimation : public RefCounted<AndroidAnimation> {
+class AndroidAnimation : public ThreadSafeRefCounted<AndroidAnimation> {
public:
AndroidAnimation(AnimatedPropertyID type,
const Animation* animation,
KeyframeValueList* operations,
double beginTime);
- AndroidAnimation(AndroidAnimation* anim);
virtual ~AndroidAnimation();
- virtual PassRefPtr<AndroidAnimation> copy() = 0;
+ void suggestBeginTime(double time);
double elapsedTime(double time);
void pickValues(double progress, int* start, int* end);
bool checkIterationsAndProgress(double time, float* finalProgress);
@@ -56,11 +55,10 @@ public:
AnimatedPropertyID type() { return m_type; }
bool fillsBackwards() { return m_fillsBackwards; }
bool fillsForwards() { return m_fillsForwards; }
-
+ int uniqueId() { return m_uniqueId; }
protected:
double m_beginTime;
- double m_elapsedTime;
double m_duration;
bool m_fillsBackwards;
bool m_fillsForwards;
@@ -70,6 +68,8 @@ protected:
String m_name;
AnimatedPropertyID m_type;
KeyframeValueList* m_operations;
+ int m_uniqueId;
+ bool m_hasFinished;
};
class AndroidOpacityAnimation : public AndroidAnimation {
@@ -80,8 +80,6 @@ public:
AndroidOpacityAnimation(const Animation* animation,
KeyframeValueList* operations,
double beginTime);
- AndroidOpacityAnimation(AndroidOpacityAnimation* anim);
- virtual PassRefPtr<AndroidAnimation> copy();
virtual void applyForProgress(LayerAndroid* layer, float progress);
};
@@ -96,9 +94,6 @@ public:
KeyframeValueList* operations,
double beginTime);
- AndroidTransformAnimation(AndroidTransformAnimation* anim);
- virtual PassRefPtr<AndroidAnimation> copy();
-
virtual void applyForProgress(LayerAndroid* layer, float progress);
};
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
index 8358b2a..9c7716c 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp
@@ -264,6 +264,7 @@ bool BaseLayerAndroid::prepareBasePictureInGL(SkRect& viewport, float scale,
// the two pages (current one and future one with the new scale factor)
if (zoomManager->didReceivedRequest()) {
float nextTiledPageTransparency = 1;
+ m_state->resetFrameworkInval();
zoomManager->processTransition(currentTime, scale, &doZoomPageSwap,
&nextTiledPageTransparency, &transparency);
nextTiledPage->prepareForDrawGL(nextTiledPageTransparency, viewportTileBounds);
@@ -370,8 +371,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect,
updateLayerPositions(visibleRect);
// For now, we render layers only if the rendering mode
// is kAllTextures or kClippedTextures
- if (m_state->layersRenderingMode() < GLWebViewState::kScrollableAndFixedLayers
- && compositedRoot->drawGL()) {
+ if (compositedRoot->drawGL()) {
if (TilesManager::instance()->layerTexturesRemain()) {
// only try redrawing for layers if layer textures remain,
// otherwise we'll repaint without getting anything done
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index a331dfc..27bd482 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -204,6 +204,7 @@ void BaseTile::markAsDirty(int unsigned pictureCount,
}
cliperator.next();
}
+
if (!intersect)
return;
@@ -268,7 +269,7 @@ void BaseTile::draw(float transparency, SkRect& rect, float scale)
}
if (m_frontTexture->readyFor(this)) {
- if (isLayerTile())
+ if (isLayerTile() && m_painter && m_painter->transform())
TilesManager::instance()->shader()->drawLayerQuad(*m_painter->transform(),
rect, m_frontTexture->m_ownTextureId,
transparency, true);
diff --git a/Source/WebCore/platform/graphics/android/ClassTracker.cpp b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
index 92d406c..eb810a8 100644
--- a/Source/WebCore/platform/graphics/android/ClassTracker.cpp
+++ b/Source/WebCore/platform/graphics/android/ClassTracker.cpp
@@ -27,6 +27,7 @@
#include "ClassTracker.h"
#include "LayerAndroid.h"
+#include "TilesManager.h"
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
@@ -35,6 +36,9 @@
#undef XLOG
#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ClassTracker", __VA_ARGS__)
+#define DEBUG_LAYERS
+#undef DEBUG_LAYERS
+
namespace WebCore {
ClassTracker* ClassTracker::instance()
@@ -66,7 +70,6 @@ void ClassTracker::decrement(String name)
m_classes.set(name, value - 1);
}
-
void ClassTracker::add(LayerAndroid* layer)
{
android::Mutex::Autolock lock(m_lock);
@@ -88,6 +91,21 @@ void ClassTracker::show()
iter->first.latin1().data(), iter->second);
}
XLOG("*** %d Layers ***", m_layers.size());
+ int nbTextures = 0;
+ int nbAllocatedTextures = 0;
+ int nbLayerTextures = 0;
+ int nbAllocatedLayerTextures = 0;
+ float textureSize = 256 * 256 * 4 / 1024.0 / 1024.0;
+ TilesManager::instance()->gatherTexturesNumbers(&nbTextures, &nbAllocatedTextures,
+ &nbLayerTextures, &nbAllocatedLayerTextures);
+ XLOG("*** textures: %d/%d (%.2f Mb), layer textures: %d/%d (%.2f Mb) : total used %.2f Mb",
+ nbAllocatedTextures, nbTextures,
+ nbAllocatedTextures * textureSize,
+ nbAllocatedLayerTextures, nbLayerTextures,
+ nbAllocatedLayerTextures * textureSize,
+ (nbAllocatedTextures + nbAllocatedLayerTextures) * textureSize);
+
+#ifdef DEBUG_LAYERS
for (unsigned int i = 0; i < m_layers.size(); i++) {
LayerAndroid* layer = m_layers[i];
XLOG("[%d/%d] layer %x (%.2f, %.2f) of type %d, refcount(%d) has texture %x has image ref %x (%x) root: %x parent: %x",
@@ -98,6 +116,7 @@ void ClassTracker::show()
layer->imageTexture(), (LayerAndroid*) layer->getRootLayer(),
(LayerAndroid*) layer->getParent());
}
+#endif
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index 81dbdae..0a8c0c1 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -98,6 +98,10 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc,
SkLayerDrawLooper* looper = new SkLayerDrawLooper;
paint->setLooper(looper)->unref();
+ // The layerDrawLooper uses at the root paint to determine the text
+ // encoding so we need to make sure it is properly configured.
+ updateForFont(paint, font);
+
// Specify the behavior of the looper
SkLayerDrawLooper::LayerInfo info;
info.fPaintBits = SkLayerDrawLooper::kEntirePaint_Bits;
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp
index d1fe51a..97a53fe 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp
@@ -562,6 +562,15 @@ void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
}
+void GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
+{
+ transformMatrix.setMatrix(
+ matrix[0], matrix[1], matrix[2], matrix[3],
+ matrix[4], matrix[5], matrix[6], matrix[7],
+ matrix[8], matrix[9], matrix[10], matrix[11],
+ matrix[12], matrix[13], matrix[14], matrix[15]);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/GLUtils.h
index b952513..68acbab 100644
--- a/Source/WebCore/platform/graphics/android/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/GLUtils.h
@@ -83,6 +83,7 @@ public:
static void updateSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
#endif
static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap);
+ static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix);
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 5206b7a..273c478 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -84,9 +84,9 @@ GLWebViewState::GLWebViewState()
, m_goingLeft(false)
, m_expandedTileBoundsX(0)
, m_expandedTileBoundsY(0)
+ , m_highEndGfx(false)
, m_scale(1)
, m_layersRenderingMode(kAllTextures)
- , m_highEndGfx(false)
{
m_viewport.setEmpty();
m_futureViewportTileBounds.setEmpty();
@@ -150,8 +150,10 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval
TilesManager::instance()->setShowVisualIndicator(showVisualIndicator);
}
-void GLWebViewState::scrolledLayer(ScrollableLayerAndroid*)
+void GLWebViewState::scrollLayer(int layerId, int x, int y)
{
+ m_treeManager.updateScrollableLayer(layerId, x, y);
+
// TODO: only inval the area of the scrolled layer instead of
// doing a fullInval()
if (m_layersRenderingMode == kSingleSurfaceRendering)
@@ -335,20 +337,25 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect,
int top = viewRect.y();
int width = viewRect.width();
int height = viewRect.height();
- glViewport(left, top, width, height);
ShaderProgram* shader = TilesManager::instance()->shader();
if (shader->program() == -1) {
XLOG("Reinit shader");
shader->init();
}
+ shader->setViewport(visibleRect, scale);
shader->setViewRect(viewRect);
- shader->setViewport(visibleRect);
shader->setWebViewRect(webViewRect);
shader->setTitleBarHeight(titleBarHeight);
shader->setScreenClip(screenClip);
shader->resetBlending();
+ shader->calculateAnimationDelta();
+
+ glViewport(left + shader->getAnimationDeltaX(),
+ top - shader->getAnimationDeltaY(),
+ width, height);
+
double currentTime = WTF::currentTime();
setViewport(visibleRect, scale);
@@ -379,6 +386,9 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded)
if (nbTexturesNeeded.full < maxTextures)
m_layersRenderingMode = kAllTextures;
+ if (!maxTextures && !nbTexturesNeeded.full)
+ m_layersRenderingMode = kAllTextures;
+
if (m_layersRenderingMode < layersRenderingMode
&& m_layersRenderingMode != kAllTextures)
invalBase = true;
@@ -428,7 +438,8 @@ void GLWebViewState::fullInval()
bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale, bool* buffersSwappedPtr)
+ IntRect& clip, float scale,
+ bool* treesSwappedPtr, bool* newTreeHasAnimPtr)
{
m_scale = scale;
TilesManager::instance()->getProfiler()->nextFrame(viewport.fLeft,
@@ -470,7 +481,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
// Upload any pending ImageTexture
// Return true if we still have some images to upload.
// TODO: upload as many textures as possible within a certain time limit
- bool ret = ImagesManager::instance()->uploadTextures();
+ bool ret = ImagesManager::instance()->prepareTextures(this);
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING)
XLOGC("WARNING, scale seems corrupted after update: %e", scale);
@@ -485,10 +496,18 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
ret |= m_treeManager.drawGL(currentTime, rect, viewport,
scale, fastSwap,
- buffersSwappedPtr, &nbTexturesNeeded);
+ treesSwappedPtr, newTreeHasAnimPtr,
+ &nbTexturesNeeded);
if (!ret)
resetFrameworkInval();
+ int nbTexturesForImages = ImagesManager::instance()->nbTextures();
+ XLOG("*** We have %d textures for images, %d full, %d clipped, total %d / %d",
+ nbTexturesForImages, nbTexturesNeeded.full, nbTexturesNeeded.clipped,
+ nbTexturesNeeded.full + nbTexturesForImages,
+ nbTexturesNeeded.clipped + nbTexturesForImages);
+ nbTexturesNeeded.full += nbTexturesForImages;
+ nbTexturesNeeded.clipped += nbTexturesForImages;
ret |= setLayersRenderingMode(nbTexturesNeeded);
FloatRect extrasclip(0, 0, rect.width(), rect.height());
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 2a6c8df..8d89704 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -214,7 +214,8 @@ public:
bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale, bool* buffersSwappedPtr);
+ IntRect& clip, float scale,
+ bool* treesSwappedPtr, bool* newTreeHasAnimPtr);
#ifdef MEASURES_PERF
void dumpMeasures();
@@ -247,7 +248,7 @@ public:
};
LayersRenderingMode layersRenderingMode() { return m_layersRenderingMode; }
- void scrolledLayer(ScrollableLayerAndroid*);
+ void scrollLayer(int layerId, int x, int y);
void invalRegion(const SkRegion& region);
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 3e062f8..6990503 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -119,8 +119,8 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_needsRepaint(false),
m_needsNotifyClient(false),
m_haveContents(false),
- m_haveImage(false),
m_newImage(false),
+ m_image(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
{
@@ -132,6 +132,9 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
GraphicsLayerAndroid::~GraphicsLayerAndroid()
{
+ if (m_image)
+ m_image->deref();
+
m_contentLayer->unref();
SkSafeUnref(m_foregroundLayer);
SkSafeUnref(m_foregroundClipLayer);
@@ -331,6 +334,9 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
void GraphicsLayerAndroid::setBackfaceVisibility(bool b)
{
+ if (b == m_backfaceVisibility)
+ return;
+
GraphicsLayer::setBackfaceVisibility(b);
m_contentLayer->setBackfaceVisibility(b);
askForSync();
@@ -397,7 +403,7 @@ void GraphicsLayerAndroid::setDrawsContent(bool drawsContent)
void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
{
- if (color == m_backgroundColor)
+ if (color == m_backgroundColor && m_backgroundColorSet)
return;
LOG("(%x) setBackgroundColor", this);
GraphicsLayer::setBackgroundColor(color);
@@ -409,6 +415,9 @@ void GraphicsLayerAndroid::setBackgroundColor(const Color& color)
void GraphicsLayerAndroid::clearBackgroundColor()
{
+ if (!m_backgroundColorSet)
+ return;
+
LOG("(%x) clearBackgroundColor", this);
GraphicsLayer::clearBackgroundColor();
askForSync();
@@ -551,7 +560,7 @@ bool GraphicsLayerAndroid::repaint()
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());
@@ -602,7 +611,14 @@ bool GraphicsLayerAndroid::repaint()
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);
+
+ // Invalidate the entire layer for now, as webkit will only send the
+ // setNeedsDisplayInRect() for the visible (clipped) scrollable area,
+ // offsetting the invals by the scroll position would not be enough.
+ // TODO: have webkit send us invals even for non visible area
+ SkRegion region;
+ region.setRect(0, 0, contentsRect.width(), contentsRect.height());
+ m_foregroundLayer->markAsDirty(region);
m_foregroundLayer->needsRepaint();
} else {
// If there is no contents clip, we can draw everything into one
@@ -633,7 +649,7 @@ bool GraphicsLayerAndroid::repaint()
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);
@@ -666,7 +682,7 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
{
// 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;
@@ -830,14 +846,23 @@ void GraphicsLayerAndroid::resumeAnimations()
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;
m_newImage = true;
- m_contentLayer->setContentsImage(image->nativeImageForCurrentFrame());
}
- if (m_haveImage && !image)
+ if (!image && m_image) {
m_contentLayer->setContentsImage(0);
+ m_image->deref();
+ m_image = 0;
+ }
setNeedsDisplay();
askForSync();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index af8d7ce..358f674 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -145,8 +145,8 @@ private:
bool m_needsNotifyClient;
bool m_haveContents;
- bool m_haveImage;
bool m_newImage;
+ Image* m_image;
SkRegion m_dirtyRegion;
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
index 96f7713..23e3899 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.cpp
@@ -27,8 +27,11 @@
#include "ImageTexture.h"
#include "ImagesManager.h"
+#include "LayerAndroid.h"
#include "SkDevice.h"
+#include "SkPicture.h"
#include "TilesManager.h"
+#include "TiledTexture.h"
#include <cutils/log.h>
#include <wtf/CurrentTime.h>
@@ -51,96 +54,201 @@
namespace WebCore {
-ImageTexture::ImageTexture(SkBitmapRef* img)
- : m_imageRef(img)
- , m_image(0)
- , m_textureId(0)
- , m_refCount(0)
+// CRC computation adapted from Tools/DumpRenderTree/CyclicRedundancyCheck.cpp
+static void makeCrcTable(unsigned crcTable[256])
+{
+ for (unsigned i = 0; i < 256; i++) {
+ unsigned c = i;
+ for (int k = 0; k < 8; k++) {
+ if (c & 1)
+ c = -306674912 ^ ((c >> 1) & 0x7fffffff);
+ else
+ c = c >> 1;
+ }
+ crcTable[i] = c;
+ }
+}
+
+unsigned computeCrc(uint8_t* buffer, size_t size)
+{
+ static unsigned crcTable[256];
+ static bool crcTableComputed = false;
+ if (!crcTableComputed) {
+ makeCrcTable(crcTable);
+ crcTableComputed = true;
+ }
+
+ unsigned crc = 0xffffffffL;
+ for (size_t i = 0; i < size; ++i)
+ crc = crcTable[(crc ^ buffer[i]) & 0xff] ^ ((crc >> 8) & 0x00ffffffL);
+ return crc ^ 0xffffffffL;
+}
+
+ImageTexture::ImageTexture(SkBitmap* bmp, unsigned crc)
+ : m_image(bmp)
+ , m_texture(0)
+ , m_layer(0)
+ , m_picture(0)
+ , m_crc(crc)
{
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("ImageTexture");
#endif
- if (!m_imageRef)
+ if (!m_image)
return;
- SkBitmap* bitmap = &m_imageRef->bitmap();
- m_image = new SkBitmap();
+ // NOTE: This constructor is called on the webcore thread
+
+ // Create a picture containing the image (needed for TiledTexture)
+ m_picture = new SkPicture();
+ SkCanvas* pcanvas = m_picture->beginRecording(m_image->width(), m_image->height());
+ pcanvas->clear(SkColorSetARGBInline(0, 0, 0, 0));
+ pcanvas->drawBitmap(*m_image, 0, 0);
+ m_picture->endRecording();
+}
+
+ImageTexture::~ImageTexture()
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("ImageTexture");
+#endif
+ delete m_image;
+ delete m_texture;
+ SkSafeUnref(m_picture);
+}
+
+SkBitmap* ImageTexture::convertBitmap(SkBitmap* bitmap)
+{
+ SkBitmap* img = new SkBitmap();
int w = bitmap->width();
int h = bitmap->height();
- m_image->setConfig(SkBitmap::kARGB_8888_Config, w, h);
- m_image->allocPixels();
- SkDevice* device = new SkDevice(NULL, *m_image, false);
+
+ // Create a copy of the image
+ img->setConfig(SkBitmap::kARGB_8888_Config, w, h);
+ img->allocPixels();
+ SkDevice* device = new SkDevice(NULL, *img, false);
SkCanvas canvas;
canvas.setDevice(device);
device->unref();
SkRect dest;
dest.set(0, 0, w, h);
- m_image->setIsOpaque(false);
- m_image->eraseARGB(0, 0, 0, 0);
+ img->setIsOpaque(false);
+ img->eraseARGB(0, 0, 0, 0);
canvas.drawBitmapRect(*bitmap, 0, dest);
+
+ return img;
}
-ImageTexture::~ImageTexture()
+unsigned ImageTexture::computeCRC(const SkBitmap* bitmap)
{
-#ifdef DEBUG_COUNT
- ClassTracker::instance()->decrement("ImageTexture");
-#endif
- delete m_image;
+ if (!bitmap)
+ return 0;
+ bitmap->lockPixels();
+ uint8_t* img = static_cast<uint8_t*>(bitmap->getPixels());
+ unsigned crc = computeCrc(img, bitmap->getSize());
+ bitmap->unlockPixels();
+ return crc;
}
-void ImageTexture::prepareGL()
+bool ImageTexture::equalsCRC(unsigned crc)
{
- if (m_textureId)
- return;
-
- ImagesManager::instance()->scheduleTextureUpload(this);
+ return m_crc == crc;
}
-void ImageTexture::uploadGLTexture()
+int ImageTexture::nbTextures()
{
- if (m_textureId)
- return;
-
- glGenTextures(1, &m_textureId);
- GLUtils::createTextureWithBitmap(m_textureId, *m_image);
+ if (!hasContentToShow())
+ return 0;
+ if (!m_texture)
+ return 0;
+
+ // TODO: take in account the visible clip (need to maintain
+ // a list of the clients layer, etc.)
+ IntRect visibleArea(0, 0, m_image->width(), m_image->height());
+ int nbTextures = m_texture->nbTextures(visibleArea, 1.0);
+ XLOG("ImageTexture %p, %d x %d needs %d textures",
+ this, m_image->width(), m_image->height(),
+ nbTextures);
+ return nbTextures;
}
-void ImageTexture::drawGL(LayerAndroid* layer)
+bool ImageTexture::hasContentToShow()
{
- if (!layer)
- return;
- if (!m_textureId)
- return;
+ // Don't display 1x1 image -- no need to allocate a full texture for this
if (!m_image)
- return;
+ return false;
+ if (m_image->width() == 1 && m_image->height() == 1)
+ return false;
+ return true;
+}
- SkRect rect;
- rect.fLeft = 0;
- rect.fTop = 0;
- rect.fRight = layer->getSize().width();
- rect.fBottom = layer->getSize().height();
- TilesManager::instance()->shader()->drawLayerQuad(*layer->drawTransform(),
- rect, m_textureId,
- layer->drawOpacity(), true);
+bool ImageTexture::prepareGL(GLWebViewState* state)
+{
+ if (!hasContentToShow())
+ return false;
+
+ if (!m_texture && m_picture) {
+ m_texture = new TiledTexture(this);
+ SkRegion region;
+ region.setRect(0, 0, m_image->width(), m_image->height());
+ m_texture->update(region, m_picture);
+ }
+
+ if (!m_texture)
+ return false;
+
+ IntRect visibleArea(0, 0, m_image->width(), m_image->height());
+ m_texture->prepare(state, 1.0, true, true, visibleArea);
+ if (m_texture->ready()) {
+ m_texture->swapTiles();
+ return false;
+ }
+ return true;
}
-void ImageTexture::drawCanvas(SkCanvas* canvas, SkRect& rect)
+const TransformationMatrix* ImageTexture::transform()
{
- canvas->drawBitmapRect(*m_image, 0, rect);
+ if (!m_layer)
+ return 0;
+
+ FloatPoint p(0, 0);
+ p = m_layer->drawTransform()->mapPoint(p);
+ IntRect layerArea = m_layer->unclippedArea();
+ 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;
+ m.scaleNonUniform(scaleW, scaleH);
+ m_layerMatrix = d.multiply(m);
+ return &m_layerMatrix;
}
-void ImageTexture::release()
+float ImageTexture::opacity()
{
- if (m_refCount >= 1)
- m_refCount--;
- if (!m_refCount)
- deleteTexture();
+ if (!m_layer)
+ return 1.0;
+ return m_layer->drawOpacity();
}
-void ImageTexture::deleteTexture()
+void ImageTexture::drawGL(LayerAndroid* layer)
+{
+ if (!layer)
+ return;
+ if (!hasContentToShow())
+ return;
+
+ // TiledTexture::draw() will call us back to know the
+ // transform and opacity, so we need to set m_layer
+ m_layer = layer;
+ if (m_texture)
+ m_texture->draw();
+ m_layer = 0;
+}
+
+void ImageTexture::drawCanvas(SkCanvas* canvas, SkRect& rect)
{
- if (m_textureId)
- glDeleteTextures(1, &m_textureId);
+ if (canvas && m_image)
+ canvas->drawBitmapRect(*m_image, 0, rect);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImageTexture.h b/Source/WebCore/platform/graphics/android/ImageTexture.h
index cea79c3..6c6a075 100644
--- a/Source/WebCore/platform/graphics/android/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/ImageTexture.h
@@ -29,57 +29,78 @@
#include "GLUtils.h"
#include "SkBitmap.h"
#include "SkBitmapRef.h"
+#include "SkPicture.h"
#include "SkRefCnt.h"
#include "LayerAndroid.h"
namespace WebCore {
class LayerAndroid;
+class TexturesResult;
+class TiledTexture;
/////////////////////////////////////////////////////////////////////////////////
// Image sharing codepath for layers
/////////////////////////////////////////////////////////////////////////////////
//
-// We receive an SkBitmapRef on the webcore thread; from this we create
-// an ImageTexture instance and keep it in TilesManager in a hashmap
-// (see TilesManager::addImage())
+// Layers containing only an image take a slightly different codepath;
+// GraphicsLayer::setContentsToImage() is called on the webcore thread,
+// passing an Image instance. We get the native image (an SkBitmap) and create
+// an ImageTexture instance with it (or increment the refcount of an existing
+// instance if the SkBitmap is similar to one already stored in ImagesManager,
+// i.e. if two GraphicsLayer share the same image).
//
-// The ImageTexture will recopy the pointed SkBitmap locally (so we can safely
-// use it on the texture generation thread), and just use the SkBitmapRef as a
-// key.
+// To detect if an image is similar, we compute and use a CRC. Each ImageTexture
+// is stored in ImagesManager using its CRC as a hash key.
+// Simply comparing the address is not enough -- different image could end up
+// at the same address (i.e. the image is deallocated then a new one is
+// reallocated at the old address)
//
-// Layers on the shared image path will ask TilesManager for the corresponding
-// ImageTexture, instead of using a PaintedSurface+TiledTexture.
-// When the ImageTexture is prepared for the first time, we directly upload
-// the bitmap to a texture.
+// Each ImageTexture's CRC being unique, LayerAndroid instances simply store that
+// and retain/release the corresponding ImageTexture (so that
+// queued painting request will work correctly and not crash...).
+// LayerAndroid running on the UI thread will get the corresponding
+// ImageTexture at draw time.
//
-// TODO: limit how many ImageTextures can be uploaded in one draw cycle
-// TODO: limit the size of ImageTextures (use a TiledTexture when needed)
+// ImageTexture recopy the original SkBitmap so that they can safely be used
+// on a different thread; it uses TiledTexture to allocate and paint the image,
+// so that we can share the same textures and limits as the rest of the layers.
//
/////////////////////////////////////////////////////////////////////////////////
-class ImageTexture {
+class ImageTexture : public SurfacePainter {
public:
- ImageTexture(SkBitmapRef* img);
+ ImageTexture(SkBitmap* bmp, unsigned crc);
virtual ~ImageTexture();
- void prepareGL();
- void uploadGLTexture();
+ bool prepareGL(GLWebViewState*);
void drawGL(LayerAndroid* painter);
void drawCanvas(SkCanvas*, SkRect&);
- void retain() { m_refCount++; }
- void release();
- unsigned int refCount() { return m_refCount; }
- SkBitmapRef* imageRef() { return m_imageRef; }
+ bool hasContentToShow();
SkBitmap* bitmap() { return m_image; }
+ unsigned imageCRC() { return m_crc; }
-private:
+ static SkBitmap* convertBitmap(SkBitmap* bitmap);
+
+ static unsigned computeCRC(const SkBitmap* bitmap);
+ bool equalsCRC(unsigned crc);
+
+ // methods used by TiledTexture
+ virtual const TransformationMatrix* transform();
+ virtual float opacity();
- void deleteTexture();
+ int nbTextures();
+
+ virtual SurfaceType type() { return SurfacePainter::ImageSurface; }
+
+private:
SkBitmapRef* m_imageRef;
SkBitmap* m_image;
- GLuint m_textureId;
- unsigned int m_refCount;
+ TiledTexture* m_texture;
+ LayerAndroid* m_layer;
+ SkPicture* m_picture;
+ TransformationMatrix m_layerMatrix;
+ unsigned m_crc;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.cpp b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
index 21f9fe9..65c41d1 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.cpp
@@ -26,6 +26,9 @@
#include "config.h"
#include "ImagesManager.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkRefCnt.h"
#include "ImageTexture.h"
#include <cutils/log.h>
@@ -59,71 +62,88 @@ ImagesManager* ImagesManager::instance()
ImagesManager* ImagesManager::gInstance = 0;
-void ImagesManager::addImage(SkBitmapRef* imgRef)
+ImageTexture* ImagesManager::setImage(SkBitmapRef* imgRef)
{
if (!imgRef)
- return;
+ return 0;
+
+ SkBitmap* bitmap = &imgRef->bitmap();
+ ImageTexture* image = 0;
+ SkBitmap* img = 0;
+ unsigned crc = 0;
+
+ img = ImageTexture::convertBitmap(bitmap);
+ crc = ImageTexture::computeCRC(img);
+
+ {
+ android::Mutex::Autolock lock(m_imagesLock);
+ if (m_images.contains(crc)) {
+ image = m_images.get(crc);
+ SkSafeRef(image);
+ return image;
+ }
+ }
+
+ // the image is not in the map, we add it
+
+ image = new ImageTexture(img, crc);
android::Mutex::Autolock lock(m_imagesLock);
- if (!m_images.contains(imgRef))
- m_images.set(imgRef, new ImageTexture(imgRef));
+ m_images.set(crc, image);
+
+ return image;
}
-void ImagesManager::removeImage(SkBitmapRef* imgRef)
+ImageTexture* ImagesManager::retainImage(unsigned imgCRC)
{
+ if (!imgCRC)
+ return 0;
+
android::Mutex::Autolock lock(m_imagesLock);
- if (!m_images.contains(imgRef))
- return;
+ ImageTexture* image = 0;
+ if (m_images.contains(imgCRC)) {
+ image = m_images.get(imgCRC);
+ SkSafeRef(image);
+ }
+ return image;
+}
- ImageTexture* image = m_images.get(imgRef);
- image->release();
+void ImagesManager::releaseImage(unsigned imgCRC)
+{
+ if (!imgCRC)
+ return;
- if (!image->refCount()) {
- m_images.remove(imgRef);
- delete image;
+ android::Mutex::Autolock lock(m_imagesLock);
+ if (m_images.contains(imgCRC)) {
+ ImageTexture* image = m_images.get(imgCRC);
+ if (image->getRefCnt() == 1)
+ m_images.remove(imgCRC);
+ SkSafeUnref(image);
}
}
-void ImagesManager::showImages()
+int ImagesManager::nbTextures()
{
- XLOGC("We have %d images", m_images.size());
- HashMap<SkBitmapRef*, ImageTexture*>::iterator end = m_images.end();
+ android::Mutex::Autolock lock(m_imagesLock);
+ HashMap<unsigned, ImageTexture*>::iterator end = m_images.end();
int i = 0;
- for (HashMap<SkBitmapRef*, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
- XLOGC("Image %x (%d/%d) has %d references", it->first, i,
- m_images.size(), it->second->refCount());
+ int nb = 0;
+ for (HashMap<unsigned, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
+ nb += it->second->nbTextures();
i++;
}
+ return nb;
}
-ImageTexture* ImagesManager::getTextureForImage(SkBitmapRef* img, bool retain)
+bool ImagesManager::prepareTextures(GLWebViewState* state)
{
+ bool ret = false;
android::Mutex::Autolock lock(m_imagesLock);
- ImageTexture* image = m_images.get(img);
- if (retain && image)
- image->retain();
- return image;
-}
-
-void ImagesManager::scheduleTextureUpload(ImageTexture* texture)
-{
- if (m_imagesToUpload.contains(texture))
- return;
-
- texture->retain();
- m_imagesToUpload.append(texture);
-}
-
-bool ImagesManager::uploadTextures()
-{
- // scheduleUpload and uploadTextures are called on the same thread
- if (!m_imagesToUpload.size())
- return false;
- ImageTexture* texture = m_imagesToUpload.last();
- texture->uploadGLTexture();
- m_imagesToUpload.removeLast();
- removeImage(texture->imageRef());
- return m_imagesToUpload.size();
+ HashMap<unsigned, ImageTexture*>::iterator end = m_images.end();
+ for (HashMap<unsigned, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
+ ret |= it->second->prepareGL(state);
+ }
+ return ret;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/ImagesManager.h b/Source/WebCore/platform/graphics/android/ImagesManager.h
index 2fcb9fd..a3ea859 100644
--- a/Source/WebCore/platform/graphics/android/ImagesManager.h
+++ b/Source/WebCore/platform/graphics/android/ImagesManager.h
@@ -35,17 +35,18 @@
namespace WebCore {
class ImageTexture;
+class GLWebViewState;
class ImagesManager {
public:
static ImagesManager* instance();
- void addImage(SkBitmapRef* img);
- void removeImage(SkBitmapRef* img);
- ImageTexture* getTextureForImage(SkBitmapRef* img, bool retain = true);
- void showImages();
- void scheduleTextureUpload(ImageTexture* texture);
- bool uploadTextures();
+ ImageTexture* setImage(SkBitmapRef* imgRef);
+ ImageTexture* retainImage(unsigned imgCRC);
+ void releaseImage(unsigned imgCRC);
+
+ bool prepareTextures(GLWebViewState*);
+ int nbTextures();
private:
ImagesManager() {}
@@ -53,8 +54,7 @@ private:
static ImagesManager* gInstance;
android::Mutex m_imagesLock;
- HashMap<SkBitmapRef*, ImageTexture*> m_images;
- Vector<ImageTexture*> m_imagesToUpload;
+ HashMap<unsigned, ImageTexture*> m_images;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 9e7626a..962bcdf 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -149,8 +149,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
m_recordingPicture(0),
m_uniqueId(++gUniqueId),
m_texture(0),
- m_imageRef(0),
- m_imageTexture(0),
+ m_imageCRC(0),
m_pictureUsed(0),
m_scale(1),
m_lastComputeTextureSize(0),
@@ -174,15 +173,15 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_isIframe(layer.m_isIframe),
m_uniqueId(layer.m_uniqueId),
m_texture(0),
- m_imageTexture(0),
m_owningLayer(layer.m_owningLayer),
m_type(LayerAndroid::UILayer),
m_hasText(true)
{
m_isFixed = layer.m_isFixed;
- m_imageRef = layer.m_imageRef;
- if (m_imageRef)
- ImagesManager::instance()->addImage(m_imageRef);
+ m_imageCRC = layer.m_imageCRC;
+ if (m_imageCRC)
+ ImagesManager::instance()->retainImage(m_imageCRC);
+
m_renderLayerPos = layer.m_renderLayerPos;
m_transform = layer.m_transform;
m_backfaceVisibility = layer.m_backfaceVisibility;
@@ -216,14 +215,13 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
KeyframesMap::const_iterator end = layer.m_animations.end();
for (KeyframesMap::const_iterator it = layer.m_animations.begin(); it != end; ++it) {
- pair<String, int> key((it->second)->name(), (it->second)->type());
- m_animations.add(key, (it->second)->copy());
+ m_animations.add(it->first, it->second);
}
m_hasText = layer.m_hasText;
#ifdef DEBUG_COUNT
- ClassTracker::instance()->increment("LayerAndroid - recopy (UI?)");
+ ClassTracker::instance()->increment("LayerAndroid - recopy (UI)");
ClassTracker::instance()->add(this);
#endif
}
@@ -252,8 +250,7 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
m_recordingPicture(picture),
m_uniqueId(++gUniqueId),
m_texture(0),
- m_imageRef(0),
- m_imageTexture(0),
+ m_imageCRC(0),
m_scale(1),
m_lastComputeTextureSize(0),
m_owningLayer(0),
@@ -272,8 +269,9 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
LayerAndroid::~LayerAndroid()
{
- if (m_imageTexture)
- ImagesManager::instance()->removeImage(m_imageTexture->imageRef());
+ if (m_imageCRC)
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+
SkSafeUnref(m_recordingPicture);
m_animations.clear();
#ifdef DEBUG_COUNT
@@ -326,6 +324,17 @@ bool LayerAndroid::evaluateAnimations(double time)
return hasRunningAnimations || m_hasRunningAnimations;
}
+void LayerAndroid::initAnimations() {
+ // tell auto-initializing animations to start now
+ for (int i = 0; i < countChildren(); i++)
+ getChild(i)->initAnimations();
+
+ KeyframesMap::const_iterator localBegin = m_animations.begin();
+ KeyframesMap::const_iterator localEnd = m_animations.end();
+ for (KeyframesMap::const_iterator localIt = localBegin; localIt != localEnd; ++localIt)
+ (localIt->second)->suggestBeginTime(WTF::currentTime());
+}
+
void LayerAndroid::addDirtyArea()
{
IntSize layerSize(getSize().width(), getSize().height());
@@ -370,7 +379,7 @@ void LayerAndroid::removeAnimationsForKeyframes(const String& name)
}
for (unsigned int i = 0; i < toDelete.size(); i++)
- m_animations.remove(toDelete[i]);
+ m_animations.remove(toDelete[i]);
}
// We only use the bounding rect of the layer as mask...
@@ -761,16 +770,14 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
void LayerAndroid::setContentsImage(SkBitmapRef* img)
{
- m_imageRef = img;
- if (!img)
- return;
-
- ImagesManager::instance()->addImage(img);
+ ImageTexture* image = ImagesManager::instance()->setImage(img);
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+ m_imageCRC = image ? image->imageCRC() : 0;
}
bool LayerAndroid::needsTexture()
{
- return m_imageRef || (m_recordingPicture
+ return m_imageCRC || (m_recordingPicture
&& m_recordingPicture->width() && m_recordingPicture->height());
}
@@ -841,10 +848,11 @@ void LayerAndroid::showLayer(int indent)
IntRect visible = visibleArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
- XLOGC("%s [%d:0x%x] - %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
+ XLOGC("%s [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d",
spaces, uniqueId(), m_owningLayer,
needsTexture() ? "needs a texture" : "no texture",
+ m_imageCRC ? "has an image" : "no image",
tr.x(), tr.y(), tr.width(), tr.height(),
visible.x(), visible.y(), visible.width(), visible.height(),
clip.x(), clip.y(), clip.width(), clip.height(),
@@ -889,7 +897,12 @@ void LayerAndroid::setIsPainting(Layer* drawingTree)
for (int i = 0; i < count; i++)
this->getChild(i)->setIsPainting(drawingTree);
- obtainTextureForPainting(static_cast<LayerAndroid*>(drawingTree));
+
+ LayerAndroid* drawingLayer = 0;
+ if (drawingTree)
+ drawingLayer = static_cast<LayerAndroid*>(drawingTree)->findById(uniqueId());
+
+ obtainTextureForPainting(drawingLayer);
}
void LayerAndroid::mergeInvalsInto(Layer* replacementTree)
@@ -950,38 +963,31 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer)
m_opacity = layer->m_opacity;
m_transform = layer->m_transform;
- if (m_imageRef != layer->m_imageRef)
+ if (m_imageCRC != layer->m_imageCRC)
m_visible = false;
if ((m_recordingPicture != layer->m_recordingPicture)
- || (m_imageRef != layer->m_imageRef))
+ || (m_imageCRC != layer->m_imageCRC))
return true;
return false;
}
-void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingTree)
+void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingLayer)
{
if (!needsTexture())
return;
- if (m_imageRef) {
- if (!m_imageTexture) {
- m_imageTexture = ImagesManager::instance()->getTextureForImage(m_imageRef);
- m_dirtyRegion.setEmpty();
- }
+ if (m_imageCRC) {
if (m_texture) {
m_texture->setDrawingLayer(0);
m_texture->clearPaintingLayer();
m_texture = 0;
}
} else {
- if (drawingTree) {
- LayerAndroid* drawingLayer = drawingTree->findById(uniqueId());
- if (drawingLayer) {
- // if a previous tree had the same layer, paint with that painted surface
- m_texture = drawingLayer->m_texture;
- }
+ if (drawingLayer) {
+ // if a previous tree had the same layer, paint with that painted surface
+ m_texture = drawingLayer->m_texture;
}
if (!m_texture)
@@ -989,8 +995,8 @@ void LayerAndroid::obtainTextureForPainting(LayerAndroid* drawingTree)
// pass the invalidated regions to the PaintedSurface
m_texture->setPaintingLayer(this, m_dirtyRegion);
- m_dirtyRegion.setEmpty();
}
+ m_dirtyRegion.setEmpty();
}
@@ -1032,9 +1038,6 @@ void LayerAndroid::prepare()
if (m_texture)
m_texture->prepare(m_state);
-
- if (m_imageTexture)
- m_imageTexture->prepareGL();
}
IntRect LayerAndroid::unclippedArea()
@@ -1115,11 +1118,16 @@ bool LayerAndroid::drawGL()
bool askScreenUpdate = false;
- if (m_texture)
- askScreenUpdate |= m_texture->draw();
-
- if (m_imageTexture)
- m_imageTexture->drawGL(this);
+ if (m_state->layersRenderingMode() < GLWebViewState::kScrollableAndFixedLayers) {
+ if (m_texture)
+ askScreenUpdate |= m_texture->draw();
+ if (m_imageCRC) {
+ ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
+ if (imageTexture)
+ imageTexture->drawGL(this);
+ ImagesManager::instance()->releaseImage(m_imageCRC);
+ }
+ }
// When the layer is dirty, the UI thread should be notified to redraw.
askScreenUpdate |= drawChildrenGL();
@@ -1216,16 +1224,15 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity)
if (canvasOpacity < 255)
canvas->setDrawFilter(new OpacityDrawFilter(canvasOpacity));
- if (m_imageRef) {
- if (!m_imageTexture) {
- m_imageTexture = ImagesManager::instance()->getTextureForImage(m_imageRef);
- m_dirtyRegion.setEmpty();
- }
- if (m_imageTexture) {
+ if (m_imageCRC) {
+ ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
+ m_dirtyRegion.setEmpty();
+ if (imageTexture) {
SkRect dest;
dest.set(0, 0, getSize().width(), getSize().height());
- m_imageTexture->drawCanvas(canvas, dest);
+ imageTexture->drawCanvas(canvas, dest);
}
+ ImagesManager::instance()->releaseImage(m_imageCRC);
}
contentDraw(canvas);
}
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index ae9dc88..c1f1bc9 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -214,6 +214,7 @@ public:
void removeAnimationsForKeyframes(const String& name);
bool evaluateAnimations();
bool evaluateAnimations(double time);
+ void initAnimations();
bool hasAnimations() const;
void addDirtyArea();
@@ -260,7 +261,7 @@ public:
/** This sets a content image -- calling it means we will use
the image directly when drawing the layer instead of using
the content painted by WebKit.
- Images are handled in TilesManager, as they can be shared
+ Images are handled in ImagesManager, as they can be shared
between layers.
*/
void setContentsImage(SkBitmapRef* img);
@@ -290,7 +291,7 @@ public:
friend void android::cleanupImageRefs(LayerAndroid* layer);
PaintedSurface* texture() { return m_texture; }
- void obtainTextureForPainting(LayerAndroid* drawingTree);
+ void obtainTextureForPainting(LayerAndroid* drawingLayer);
// Update layers using another tree. Only works for basic properties
// such as the position, the transform. Return true if anything more
@@ -298,13 +299,13 @@ public:
bool updateWithTree(LayerAndroid*);
virtual bool updateWithLayer(LayerAndroid*);
- SkBitmapRef* imageRef() { return m_imageRef; }
- ImageTexture* imageTexture() { return m_imageTexture; }
int type() { return m_type; }
bool hasText() { return m_hasText; }
void checkTextPresence();
+ void copyAnimationStartTimesRecursive(LayerAndroid* oldTree);
+
// rendering asset management
void swapTiles();
void setIsDrawing(bool isDrawing);
@@ -323,6 +324,7 @@ private:
friend class CachedLayer::Debug; // debugging access only
#endif
+ void copyAnimationStartTimes(LayerAndroid* oldLayer);
void findInner(FindState&) const;
bool prepareContext(bool force = false);
void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const;
@@ -386,8 +388,7 @@ private:
int m_uniqueId;
PaintedSurface* m_texture;
- SkBitmapRef* m_imageRef;
- ImageTexture* m_imageTexture;
+ unsigned m_imageCRC;
unsigned int m_pictureUsed;
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
index 5d06ea3..2d69706 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.cpp
@@ -25,12 +25,14 @@
#include "config.h"
#include "PaintTileOperation.h"
+#include "ImageTexture.h"
+#include "ImagesManager.h"
#include "LayerAndroid.h"
#include "PaintedSurface.h"
namespace WebCore {
-PaintTileOperation::PaintTileOperation(BaseTile* tile, PaintedSurface* surface)
+PaintTileOperation::PaintTileOperation(BaseTile* tile, SurfacePainter* surface)
: QueuedOperation(QueuedOperation::PaintTile, tile->page())
, m_tile(tile)
, m_surface(surface)
@@ -46,7 +48,13 @@ PaintTileOperation::~PaintTileOperation()
m_tile->setRepaintPending(false);
m_tile = 0;
}
- SkSafeUnref(m_surface);
+
+ if (m_surface && m_surface->type() == SurfacePainter::ImageSurface) {
+ ImageTexture* image = static_cast<ImageTexture*>(m_surface);
+ ImagesManager::instance()->releaseImage(image->imageCRC());
+ } else {
+ SkSafeUnref(m_surface);
+ }
}
bool PaintTileOperation::operator==(const QueuedOperation* operation)
diff --git a/Source/WebCore/platform/graphics/android/PaintTileOperation.h b/Source/WebCore/platform/graphics/android/PaintTileOperation.h
index fabc2f7..bc74d03 100644
--- a/Source/WebCore/platform/graphics/android/PaintTileOperation.h
+++ b/Source/WebCore/platform/graphics/android/PaintTileOperation.h
@@ -28,15 +28,17 @@
#include "BaseTile.h"
#include "QueuedOperation.h"
+#include "SkRefCnt.h"
namespace WebCore {
class LayerAndroid;
-class PaintedSurface;
+class SurfacePainter;
+class ImageTexture;
class PaintTileOperation : public QueuedOperation {
public:
- PaintTileOperation(BaseTile* tile, PaintedSurface* surface = 0);
+ PaintTileOperation(BaseTile* tile, SurfacePainter* surface = 0);
virtual ~PaintTileOperation();
virtual bool operator==(const QueuedOperation* operation);
virtual void run();
@@ -47,7 +49,7 @@ public:
private:
BaseTile* m_tile;
- PaintedSurface* m_surface;
+ SurfacePainter* m_surface;
};
class ScaleFilter : public OperationFilter {
diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp
index d3c1e15..45c7579 100644
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.cpp
+++ b/Source/WebCore/platform/graphics/android/PaintedSurface.cpp
@@ -52,9 +52,8 @@
#endif // DEBUG
-// Allows layers using less than MAX_UNCLIPPED_AREA tiles to
-// schedule all of them instead of clipping the area with the visible rect.
-#define MAX_UNCLIPPED_AREA 16
+// Layers with an area larger than 2048*2048 should never be unclipped
+#define MAX_UNCLIPPED_AREA 4194304
namespace WebCore {
@@ -203,10 +202,14 @@ IntRect PaintedSurface::computeVisibleArea(LayerAndroid* layer) {
return area;
if (!layer->contentIsScrollable()
- && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures)
+ && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
area = layer->unclippedArea();
- else
+ double total = ((double) area.width()) * ((double) area.height());
+ if (total > MAX_UNCLIPPED_AREA)
+ area = layer->visibleArea();
+ } else {
area = layer->visibleArea();
+ }
return area;
}
diff --git a/Source/WebCore/platform/graphics/android/PaintedSurface.h b/Source/WebCore/platform/graphics/android/PaintedSurface.h
index b438111..b8ab7b8 100644
--- a/Source/WebCore/platform/graphics/android/PaintedSurface.h
+++ b/Source/WebCore/platform/graphics/android/PaintedSurface.h
@@ -43,7 +43,7 @@ namespace WebCore {
class DualTiledTexture;
-class PaintedSurface : public SkRefCnt {
+class PaintedSurface : public SurfacePainter {
public:
PaintedSurface();
virtual ~PaintedSurface();
@@ -71,10 +71,10 @@ public:
// TilePainter methods for TiledTexture
virtual const TransformationMatrix* transform();
+ virtual float opacity();
// used by TiledTexture
float scale() { return m_scale; }
- float opacity();
unsigned int pictureUsed() { return m_pictureUsed; }
private:
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
index 2643d2c..3c2ced5 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.cpp
@@ -22,9 +22,6 @@ bool ScrollableLayerAndroid::scrollTo(int x, int y)
setPosition(m_scrollLimits.fLeft - newX, m_scrollLimits.fTop - newY);
- if (state())
- state()->scrolledLayer(this);
-
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
index cc9c810..2a6a488 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp
@@ -195,6 +195,8 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag
ShaderProgram::ShaderProgram()
: m_blendingEnabled(false)
, m_contrast(1)
+ , m_alphaLayer(false)
+ , m_currentScale(1.0f)
{
init();
}
@@ -286,13 +288,14 @@ void ShaderProgram::setBlendingState(bool enableBlending)
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////
-void ShaderProgram::setViewport(SkRect& viewport)
+void ShaderProgram::setViewport(SkRect& viewport, float scale)
{
TransformationMatrix ortho;
GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop,
viewport.fRight, viewport.fBottom, -1000, 1000);
m_projectionMatrix = ortho;
m_viewport = viewport;
+ m_currentScale = scale;
}
void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle)
@@ -302,7 +305,12 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrix
TransformationMatrix scale;
scale.scale3d(geometry.width(), geometry.height(), 1.0);
- TransformationMatrix total = m_projectionMatrix * translate * scale;
+ TransformationMatrix total;
+ if (!m_alphaLayer)
+ total = m_projectionMatrix * m_repositionMatrix * m_webViewMatrix
+ * translate * scale;
+ else
+ total = m_projectionMatrix * translate * scale;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, total);
@@ -560,7 +568,13 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
// move the drawing depending on where the texture is on the layer
modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop);
modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1);
- TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
+
+ TransformationMatrix renderMatrix;
+ if (!m_alphaLayer)
+ renderMatrix = m_projectionMatrix * m_repositionMatrix
+ * m_webViewMatrix * modifiedDrawMatrix;
+ else
+ renderMatrix = m_projectionMatrix * modifiedDrawMatrix;
GLfloat projectionMatrix[16];
GLUtils::toGLMatrix(projectionMatrix, renderMatrix);
@@ -627,6 +641,44 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
+void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer)
+{
+ GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix);
+ m_alphaLayer = alphaLayer;
+}
+
+void ShaderProgram::calculateAnimationDelta()
+{
+ // The matrix contains the scrolling info, so this rect is starting from
+ // the m_viewport.
+ // So we just need to map the webview's visible rect using the matrix,
+ // calculate the difference b/t transformed rect and the webViewRect,
+ // then we can get the delta x , y caused by the animation.
+ // Note that the Y is for reporting back to GL viewport, so it is inverted.
+ // When it is alpha animation, then we rely on the framework implementation
+ // such that there is no matrix applied in native webkit.
+ if (!m_alphaLayer) {
+ FloatRect rect(m_viewport.fLeft * m_currentScale,
+ m_viewport.fTop * m_currentScale,
+ m_webViewRect.width(),
+ m_webViewRect.height());
+ rect = m_webViewMatrix.mapRect(rect);
+ m_animationDelta.setX(rect.x() - m_webViewRect.x() );
+ m_animationDelta.setY(rect.y() + rect.height() - m_webViewRect.y()
+ - m_webViewRect.height() - m_titleBarHeight);
+
+ m_repositionMatrix.makeIdentity();
+ m_repositionMatrix.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0);
+ m_repositionMatrix.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0);
+ m_repositionMatrix.translate3d(-m_animationDelta.x(), -m_animationDelta.y(), 0);
+ } else {
+ m_animationDelta.setX(0);
+ m_animationDelta.setY(0);
+ m_repositionMatrix.makeIdentity();
+ }
+
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h
index b309872..9ab7a46 100644
--- a/Source/WebCore/platform/graphics/android/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h
@@ -36,7 +36,7 @@ public:
int program() { return m_program; }
// Drawing
- void setViewport(SkRect& viewport);
+ void setViewport(SkRect& viewport, float scale);
float zValue(const TransformationMatrix& drawMatrix, float w, float h);
// For drawQuad and drawLayerQuad, they can handle 3 cases for now:
@@ -88,6 +88,18 @@ public:
contrast = MAX_CONTRAST;
m_contrast = contrast;
}
+ void setWebViewMatrix(const float* matrix, bool alphaLayer);
+
+ // This delta is the delta from the layout pos and the current animation pos.
+ // Basically, in terms of layout, the webview is still in the original layout
+ // pos, as without animation. Such that the viewport and visible rect etc are
+ // still in that pos, too, except the clipping info.
+ // Our rendering approach is after applying all the matrix, webView is
+ // rendered as if it was at the original layout pos, but then offset the
+ // glViewport to match the animation.
+ void calculateAnimationDelta();
+ int getAnimationDeltaX() { return m_animationDelta.x(); }
+ int getAnimationDeltaY() { return m_animationDelta.y(); }
private:
GLuint loadShader(GLenum shaderType, const char* pSource);
@@ -158,6 +170,22 @@ private:
GLint m_hPosition;
GLint m_hPositionInverted;
GLint m_hVideoPosition;
+
+ bool m_alphaLayer;
+ TransformationMatrix m_webViewMatrix;
+ float m_currentScale;
+
+ // After the webViewTranform, we need to reposition the rect to match our viewport.
+ // Basically, the webViewTransformMatrix should apply on the screen resolution.
+ // So we start by doing the scale and translate to get each tile into screen coordinates.
+ // After applying the webViewTransformMatrix, b/c the way it currently set up
+ // for scroll and titlebar, we need to offset both of them.
+ // Finally, map everything back to (-1, 1) by using the m_projectionMatrix.
+ // TODO: Given that m_webViewMatrix contains most of the tranformation
+ // information, we should be able to get rid of some parameter we got from
+ // Java side and simplify our code.
+ TransformationMatrix m_repositionMatrix;
+ IntPoint m_animationDelta;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
index 0820688..bccb99b 100644
--- a/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
+++ b/Source/WebCore/platform/graphics/android/TexturesGenerator.cpp
@@ -184,11 +184,10 @@ bool TexturesGenerator::threadLoop()
m_currentOperation->run();
}
+ QueuedOperation* oldOperation = m_currentOperation;
mRequestedOperationsLock.lock();
- if (m_currentOperation) {
- delete m_currentOperation;
+ if (m_currentOperation)
m_currentOperation = 0;
- }
if (!mRequestedOperations.size())
stop = true;
if (m_waitForCompletion) {
@@ -197,7 +196,8 @@ bool TexturesGenerator::threadLoop()
mRequestedOperationsCond.signal();
}
mRequestedOperationsLock.unlock();
-
+ if (oldOperation)
+ delete oldOperation; // delete outside lock
}
XLOG("threadLoop empty");
diff --git a/Source/WebCore/platform/graphics/android/TilePainter.h b/Source/WebCore/platform/graphics/android/TilePainter.h
index 91030cb..4d0f5dc 100644
--- a/Source/WebCore/platform/graphics/android/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/TilePainter.h
@@ -27,6 +27,7 @@
#define TilePainter_h
#include "TransformationMatrix.h"
+#include "SkRefCnt.h"
class SkCanvas;
@@ -41,6 +42,15 @@ public:
virtual const TransformationMatrix* transform() { return 0; }
};
+class SurfacePainter : public SkRefCnt {
+public:
+ virtual ~SurfacePainter() { }
+ virtual const TransformationMatrix* transform() { return 0; }
+ virtual float opacity() { return 1.0; }
+ enum SurfaceType { PaintedSurface, ImageSurface };
+ virtual SurfaceType type() { return PaintedSurface; }
+};
+
}
#endif // TilePainter_h
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index e33d39a..31a0593 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -242,9 +242,6 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
int nbTilesWidth = tileBounds.width();
int nbTilesHeight = tileBounds.height();
- int lastTileX = tileBounds.fRight - 1;
- int lastTileY = tileBounds.fBottom - 1;
-
// Expand number of tiles to allow tiles outside of viewport to be prepared for
// smoother scrolling.
int nTilesToPrepare = nbTilesWidth * nbTilesHeight;
@@ -256,21 +253,31 @@ void TiledPage::prepare(bool goingDown, bool goingLeft, const SkIRect& tileBound
int expandY = m_glWebViewState->expandedTileBoundsY();
firstTileX -= expandX;
- lastTileX += expandX;
nbTilesWidth += expandX * 2;
firstTileY -= expandY;
- lastTileY += expandY;
nbTilesHeight += expandY * 2;
}
- // crop the prepared region to the contents of the base layer
- float maxWidthTiles = m_glWebViewState->baseContentWidth() * m_scale / TilesManager::tileWidth();
- float maxHeightTiles = m_glWebViewState->baseContentHeight() * m_scale / TilesManager::tileHeight();
- firstTileX = std::max(0, firstTileX);
- firstTileY = std::max(0, firstTileY);
- lastTileX = std::min(lastTileX, static_cast<int>(ceilf(maxWidthTiles)) - 1);
- lastTileY = std::min(lastTileY, static_cast<int>(ceilf(maxHeightTiles)) - 1);
+ // crop the tile bounds in each dimension to the larger of the base layer or viewport
+ float maxBaseX = m_glWebViewState->baseContentWidth() * m_scale / TilesManager::tileWidth();
+ float maxBaseY = m_glWebViewState->baseContentHeight() * m_scale / TilesManager::tileHeight();
+ int maxX = std::max(static_cast<int>(ceilf(maxBaseX)),
+ m_glWebViewState->viewportTileBounds().width());
+ int maxY = std::max(static_cast<int>(ceilf(maxBaseY)),
+ m_glWebViewState->viewportTileBounds().height());
+
+ // adjust perimeter to not go outside cropped region
+ if (firstTileX < 0) {
+ nbTilesWidth += firstTileX;
+ firstTileX = 0;
+ }
+ if (firstTileY < 0) {
+ nbTilesHeight += firstTileY;
+ firstTileY = 0;
+ }
+ nbTilesWidth = std::min(nbTilesWidth, maxX - firstTileX);
+ nbTilesHeight = std::min(nbTilesHeight, maxY - firstTileY);
// check against corrupted scale values giving bad height/width (use float to avoid overflow)
float numTiles = static_cast<float>(nbTilesHeight) * static_cast<float>(nbTilesWidth);
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.cpp b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
index 5538e1b..d538416 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.cpp
@@ -204,6 +204,7 @@ void TiledTexture::prepareTile(bool repaint, int x, int y)
if (tile->isDirty() || !tile->frontTexture())
tile->reserveTexture();
+
bool hasPicture = m_paintingPicture != 0; // safely read on UI thread, since only UI thread writes
if (tile->backTexture() && tile->isDirty() && !tile->isRepaintPending() && hasPicture) {
PaintTileOperation *operation = new PaintTileOperation(tile, m_surface);
@@ -223,12 +224,26 @@ BaseTile* TiledTexture::getTile(int x, int y)
int TiledTexture::nbTextures(IntRect& area, float scale)
{
- IntRect computedTilesArea = computeTilesArea(area, scale);
- return computedTilesArea.width() * computedTilesArea.height();
+ IntRect tileBounds = computeTilesArea(area, scale);
+ int numberTextures = tileBounds.width() * tileBounds.height();
+
+ // add the number of dirty tiles in the bounds, as they take up double
+ // textures for double buffering
+ for (unsigned int i = 0; i <m_tiles.size(); i++) {
+ BaseTile* tile = m_tiles[i];
+ if (tile->isDirty()
+ && tile->x() >= tileBounds.x() && tile->x() <= tileBounds.maxX()
+ && tile->y() >= tileBounds.y() && tile->y() <= tileBounds.maxY())
+ numberTextures++;
+ }
+ return numberTextures;
}
bool TiledTexture::draw()
{
+ if (!m_surface)
+ return true;
+
XLOG("TT %p draw", this);
#ifdef DEBUG
@@ -257,8 +272,8 @@ bool TiledTexture::draw()
rect.fTop = tile->y() * tileHeight;
rect.fRight = rect.fLeft + tileWidth;
rect.fBottom = rect.fTop + tileHeight;
- XLOG("- [%d], { painter %x vs %x }, tile %x %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
- i, this, tile->painter(), tile, tile->x(), tile->y(),
+ XLOG("- [%d], { painter %x vs %x }, tile %x (layer tile: %d) %d,%d at scale %.2f vs %.2f [ready: %d] dirty: %d",
+ i, this, tile->painter(), tile, tile->isLayerTile(), tile->x(), tile->y(),
tile->scale(), m_scale, tile->isTileReady(), tile->isDirty());
tile->draw(m_surface->opacity(), rect, m_scale);
#ifdef DEBUG
@@ -283,7 +298,7 @@ bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* picture
return false;
}
- XLOG("TT %p painting with picture %p", this, picture);
+ XLOG("TT %p painting tile %d, %d with picture %p", this, tile->x(), tile->y(), picture);
canvas->drawPicture(*picture);
@@ -294,6 +309,8 @@ bool TiledTexture::paint(BaseTile* tile, SkCanvas* canvas, unsigned int* picture
const TransformationMatrix* TiledTexture::transform()
{
+ if (!m_surface)
+ return 0;
return m_surface->transform();
}
@@ -323,7 +340,7 @@ bool TiledTexture::owns(BaseTileTexture* texture)
return false;
}
-DualTiledTexture::DualTiledTexture(PaintedSurface* surface)
+DualTiledTexture::DualTiledTexture(SurfacePainter* surface)
{
m_textureA = new TiledTexture(surface);
m_textureB = new TiledTexture(surface);
@@ -364,6 +381,7 @@ void DualTiledTexture::prepare(GLWebViewState* state, float scale, bool repaint,
if (m_zooming && m_zoomUpdateTime < WTF::currentTime()) {
m_backTexture->prepare(state, m_futureScale, repaint, startFastSwap, visibleArea);
if (m_backTexture->ready()) {
+ m_backTexture->swapTiles();
swap();
m_zooming = false;
}
diff --git a/Source/WebCore/platform/graphics/android/TiledTexture.h b/Source/WebCore/platform/graphics/android/TiledTexture.h
index b761880..444ab14 100644
--- a/Source/WebCore/platform/graphics/android/TiledTexture.h
+++ b/Source/WebCore/platform/graphics/android/TiledTexture.h
@@ -39,11 +39,9 @@ class SkCanvas;
namespace WebCore {
-class PaintedSurface;
-
class TiledTexture : public TilePainter {
public:
- TiledTexture(PaintedSurface* surface)
+ TiledTexture(SurfacePainter* surface)
: m_paintingPicture(0)
, m_surface(surface)
, m_prevTileX(0)
@@ -82,8 +80,6 @@ public:
float scale() { return m_scale; }
bool ready();
- PaintedSurface* surface() { return m_surface; }
-
int nbTextures(IntRect& area, float scale);
private:
@@ -95,7 +91,7 @@ private:
android::Mutex m_paintingPictureSync;
SkPicture* m_paintingPicture;
- PaintedSurface* m_surface;
+ SurfacePainter* m_surface;
Vector<BaseTile*> m_tiles;
// tile coordinates in viewport, set in prepare()
@@ -112,7 +108,7 @@ private:
class DualTiledTexture {
public:
- DualTiledTexture(PaintedSurface* surface);
+ DualTiledTexture(SurfacePainter* surface);
~DualTiledTexture();
void prepare(GLWebViewState* state, float scale, bool repaint,
bool startFastSwap, IntRect& area);
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index 219435d..30bd8d0 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -189,6 +189,23 @@ void TilesManager::deallocateTexturesVector(unsigned long long sparedDrawCount,
dealloc, max, maxLayer);
}
+void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
+ int* nbLayerTextures, int* nbAllocatedLayerTextures)
+{
+ *nbTextures = m_textures.size();
+ for (unsigned int i = 0; i < m_textures.size(); i++) {
+ BaseTileTexture* texture = m_textures[i];
+ if (texture->m_ownTextureId)
+ *nbAllocatedTextures += 1;
+ }
+ *nbLayerTextures = m_tilesTextures.size();
+ for (unsigned int i = 0; i < m_tilesTextures.size(); i++) {
+ BaseTileTexture* texture = m_tilesTextures[i];
+ if (texture->m_ownTextureId)
+ *nbAllocatedLayerTextures += 1;
+ }
+}
+
void TilesManager::printTextures()
{
#ifdef DEBUG
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 0c3e900..9782fbb 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -88,6 +88,8 @@ public:
void gatherLayerTextures();
void gatherTextures();
bool layerTexturesRemain() { return m_layerTexturesRemain; }
+ void gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
+ int* nbLayerTextures, int* nbAllocatedLayerTextures);
BaseTileTexture* getAvailableTexture(BaseTile* owner);
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index b92edaf..b20ec7a 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -50,7 +50,7 @@
#endif // DEBUG
-#define ST_BUFFER_NUMBER 4
+#define ST_BUFFER_NUMBER 6
// Set this to 1 if we would like to take the new GpuUpload approach which
// relied on the glCopyTexSubImage2D instead of a glDraw call
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp
index 5fd3b7c..b7eaacf 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TreeManager.cpp
@@ -28,6 +28,7 @@
#include "Layer.h"
#include "BaseLayerAndroid.h"
+#include "ScrollableLayerAndroid.h"
#include "TilesManager.h"
#include <cutils/log.h>
@@ -87,6 +88,8 @@ void TreeManager::swap()
// painting tree becomes the drawing tree
XLOG("drawing tree %p", m_paintingTree);
m_paintingTree->setIsDrawing(true);
+ if (m_paintingTree->countChildren())
+ static_cast<LayerAndroid*>(m_paintingTree->getChild(0))->initAnimations();
if (m_queuedTree) {
// start painting with the queued tree
@@ -132,6 +135,10 @@ void TreeManager::clearTrees()
// or start painting it if we aren't
void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
{
+ XLOG("updateWithTree - %p, has children %d, has animations %d",
+ newTree, newTree && newTree->countChildren(),
+ newTree && newTree->countChildren()
+ ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
// can't have a queued tree unless have a painting tree too
ASSERT(m_paintingTree || !m_queuedTree);
@@ -143,10 +150,6 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
if (!newTree || brandNew) {
clearTrees();
if (brandNew) {
- m_animationOffset = 0;
- m_isAnimating = false;
- m_lastFrameTime = WTF::currentTime();
-
m_paintingTree = newTree;
m_paintingTree->setIsPainting(m_drawingTree);
}
@@ -159,6 +162,11 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
// have a queued tree, copy over invals so the regions are
// eventually repainted
m_queuedTree->mergeInvalsInto(newTree);
+
+ XLOG("DISCARDING tree - %p, has children %d, has animations %d",
+ newTree, newTree && newTree->countChildren(),
+ newTree && newTree->countChildren()
+ ? static_cast<LayerAndroid*>(newTree->getChild(0))->hasAnimations() : 0);
}
SkSafeUnref(m_queuedTree);
m_queuedTree = newTree;
@@ -170,9 +178,26 @@ void TreeManager::updateWithTree(Layer* newTree, bool brandNew)
m_paintingTree->setIsPainting(m_drawingTree);
}
+void TreeManager::updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y)
+{
+ LayerAndroid* layer;
+ if (tree && tree->countChildren()) {
+ layer = static_cast<LayerAndroid*>(tree->getChild(0))->findById(layerId);
+ if (layer && layer->contentIsScrollable())
+ static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
+ }
+}
+
+void TreeManager::updateScrollableLayer(int layerId, int x, int y)
+{
+ updateScrollableLayerInTree(m_queuedTree, layerId, x, y);
+ updateScrollableLayerInTree(m_paintingTree, layerId, x, y);
+ updateScrollableLayerInTree(m_drawingTree, layerId, x, y);
+}
+
bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* buffersSwappedPtr,
+ bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
TexturesResult* texturesResultPtr)
{
m_fastSwapMode |= enterFastSwapMode;
@@ -183,19 +208,28 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
bool ret = false;
bool didTreeSwap = false;
if (m_paintingTree) {
+ XLOG("preparing painting tree %p", m_paintingTree);
+
+ LayerAndroid* laTree = 0;
+ if (m_paintingTree->countChildren()) {
+ laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0));
+ ret |= laTree->evaluateAnimations(currentTime);
+ }
+
ret |= m_paintingTree->prepare(currentTime, viewRect,
visibleRect, scale);
- if (m_paintingTree->countChildren()) {
- LayerAndroid* laTree = static_cast<LayerAndroid*>(m_paintingTree->getChild(0));
+ if (laTree)
laTree->computeTexturesAmount(texturesResultPtr);
- }
+
if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) {
XLOG("have painting tree %p ready, swapping!", m_paintingTree);
didTreeSwap = true;
swap();
- if (buffersSwappedPtr)
- *buffersSwappedPtr = true;
+ if (treesSwappedPtr)
+ *treesSwappedPtr = true;
+ if (laTree && newTreeHasAnimPtr)
+ *newTreeHasAnimPtr = laTree->hasAnimations();
}
} else if (m_drawingTree) {
XLOG("preparing drawing tree %p", m_drawingTree);
@@ -207,17 +241,11 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
}
}
- if (!m_isAnimating) {
- m_animationOffset += currentTime - m_lastFrameTime;
-#ifdef ANIM_DEBUG
- XLOGC("adding to %f", m_animationOffset);
-#endif
- }
if (m_drawingTree) {
bool drawingReady = didTreeSwap || m_drawingTree->isReady();
- if (drawingReady || m_fastSwapMode)
+ if (didTreeSwap || m_fastSwapMode || (drawingReady && !m_paintingTree))
m_drawingTree->swapTiles();
if (drawingReady) {
@@ -229,18 +257,8 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
}
if (m_drawingTree->countChildren()) {
-#ifdef ANIM_DEBUG
- XLOGC("drawing tree %p with animation time offset of %f, locked %d",
- m_drawingTree, m_animationOffset, m_isAnimating);
-#endif
LayerAndroid* laTree = static_cast<LayerAndroid*>(m_drawingTree->getChild(0));
- m_isAnimating = laTree->evaluateAnimations(currentTime - m_animationOffset);
- if (!m_isAnimating)
- m_animationOffset = 0;
- ret |= m_isAnimating;
- } else if (!m_paintingTree) {
- m_animationOffset = 0;
- m_isAnimating = false;
+ ret |= laTree->evaluateAnimations(currentTime);
}
XLOG("drawing tree %p", m_drawingTree);
ret |= m_drawingTree->drawGL(viewRect, visibleRect, scale);
@@ -250,8 +268,6 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect,
m_paintingTree->state()->drawBackground(defaultBackground);
}
- m_lastFrameTime = currentTime;
-
if (m_paintingTree) {
XLOG("still have painting tree %p", m_paintingTree);
return true;
diff --git a/Source/WebCore/platform/graphics/android/TreeManager.h b/Source/WebCore/platform/graphics/android/TreeManager.h
index 09b1bd9..83d5300 100644
--- a/Source/WebCore/platform/graphics/android/TreeManager.h
+++ b/Source/WebCore/platform/graphics/android/TreeManager.h
@@ -28,6 +28,7 @@
#include "TestExport.h"
#include <utils/threads.h>
+#include "PerformanceMonitor.h"
class Layer;
class SkRect;
@@ -46,9 +47,11 @@ public:
void updateWithTree(Layer* tree, bool brandNew);
+ void updateScrollableLayer(int layerId, int x, int y);
+
bool drawGL(double currentTime, IntRect& viewRect,
SkRect& visibleRect, float scale,
- bool enterFastSwapMode, bool* buffersSwappedPtr,
+ bool enterFastSwapMode, bool* treesSwappedPtr, bool* newTreeHasAnimPtr,
TexturesResult* texturesResultPtr);
void drawCanvas(SkCanvas* canvas, bool drawLayers);
@@ -60,6 +63,8 @@ public:
int baseContentHeight();
private:
+ static void updateScrollableLayerInTree(Layer* tree, int layerId, int x, int y);
+
void swap();
void clearTrees();
@@ -70,10 +75,7 @@ private:
Layer* m_queuedTree;
bool m_fastSwapMode;
-
- double m_animationOffset;
- double m_lastFrameTime;
- bool m_isAnimating;
+ PerformanceMonitor m_perf;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index d4e2aa3..df20063 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -812,7 +812,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintLogica
else {
#ifdef ANDROID_LAYOUT
// ignore text wrap for textField or menuList
- if (doTextWrap && (o->isTextField() || o->isMenuList() || o->isFloating()))
+ if (doTextWrap && (o->isTextField() || o->isMenuList()))
doTextWrap = false;
#endif
if (o->isFloating())
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 80d5699..fb1dd2c 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -1562,6 +1562,13 @@ void RenderBox::computeLogicalWidth()
// https://bugs.webkit.org/show_bug.cgi?id=46418
if (hasOverrideSize() && parent()->style()->boxOrient() == HORIZONTAL
&& parent()->isFlexibleBox() && parent()->isFlexingChildren()) {
+#if PLATFORM(ANDROID)
+ // Strangely, the slider is get overrided as width 0 on youtube.com
+ // The wrong width will cause the touch hit test for the slider failed.
+ // This WAR should be safe since it is only targeted to slider.
+ // TODO: root cause this and see if any webkit update fix this.
+ if (!(isSlider() && overrideSize() == 0))
+#endif
setLogicalWidth(overrideSize());
return;
}
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 904b1b2..cdc4c05 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -1419,8 +1419,15 @@ void RenderLayer::scrollTo(int x, int y)
}
// Just schedule a full repaint of our object.
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // On android, scrollable areas are put on composited layers, so we
+ // do not need to repaint simply because we are scrolling
+ if (view && !hasOverflowScroll())
+ renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+#else
if (view)
renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
+#endif
// Schedule the scroll DOM event.
renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 5827636..1ef3b77 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -1576,7 +1576,12 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render
return false;
if (AnimationController* animController = renderer->animation()) {
+#if PLATFORM(ANDROID)
+ // android renders an opacity animation much faster if it's composited
+ return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity))
+#else
return (animController->isRunningAnimationOnRenderer(renderer, CSSPropertyOpacity) && inCompositingMode())
+#endif
|| animController->isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
}
return false;