summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2011-06-06 17:31:38 -0700
committerJohn Reck <jreck@google.com>2011-06-07 13:40:23 -0700
commitd68563709fdf68c90c730155149f6149b084730a (patch)
tree9ed48c92bbaff2f66fcc6778b9b650134bc68bc6
parentdfadaafc15c16563aba837f05c778eaa2a433a8b (diff)
downloadexternal_webkit-d68563709fdf68c90c730155149f6149b084730a.zip
external_webkit-d68563709fdf68c90c730155149f6149b084730a.tar.gz
external_webkit-d68563709fdf68c90c730155149f6149b084730a.tar.bz2
Serialize LayerAndroid
For now skip other layer types Doesn't support animtations Change-Id: Id1ff75f3d4d213f56561fc5d9c01f7ffee05cc79
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp7
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h30
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h3
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp328
-rw-r--r--Source/WebKit/android/nav/WebView.cpp5
6 files changed, 368 insertions, 13 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index 927b0bb..c2fd9dd 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -225,8 +225,8 @@ void GLWebViewState::inval(const IntRect& rect)
else
m_frameworkInval.unite(rect);
XLOG("intermediate invalRect(%d, %d, %d, %d) after unite with rect %d %d %d %d", m_frameworkInval.x(),
- m_frameworkInval.y(), m_frameworkInval.right(), m_frameworkInval.bottom(),
- rect.x(), rect.y(), rect.right(), rect.bottom());
+ m_frameworkInval.y(), m_frameworkInval.width(), m_frameworkInval.height(),
+ rect.x(), rect.y(), rect.width(), rect.height());
}
} else {
m_invalidateRegion.op(rect.x(), rect.y(), rect.maxX(), rect.maxY(), SkRegion::kUnion_Op);
@@ -521,7 +521,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
}
XLOG("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)",
- rect.x(), rect.y(), rect.right(), rect.bottom(),
+ rect.x(), rect.y(), rect.width(), rect.height(),
viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
resetLayersDirtyArea();
@@ -553,7 +553,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
invalRect->setHeight(inval.height());
XLOG("invalRect(%d, %d, %d, %d)", inval.x(),
- inval.y(), inval.right(), inval.bottom());
+ inval.y(), inval.width(), inval.height());
} else {
resetFrameworkInval();
}
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index 34c02e9..67456a3 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -510,6 +510,9 @@ const LayerAndroid* LayerAndroid::find(int* xPtr, int* yPtr, SkPicture* root) co
void LayerAndroid::updateFixedLayersPositions(SkRect viewport, LayerAndroid* parentIframeLayer)
{
+ XLOG("updating fixed positions, using viewport %fx%f - %fx%f",
+ viewport.fLeft, viewport.fTop,
+ viewport.width(), viewport.height());
// If this is an iframe, accumulate the offset from the parent with
// current position, and change the parent pointer.
if (m_isIframe) {
@@ -952,9 +955,9 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
if (textureInfo && (!m_contentsImage || (ready && m_contentsImage))) {
SkRect bounds;
bounds.set(m_drawingTexture->rect());
- XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %d, %d, %d, %d)",
+ XLOG("LayerAndroid %d %x (%.2f, %.2f) drawGL (texture %x, %f, %f, %f, %f)",
uniqueId(), this, getWidth(), getHeight(),
- m_drawingTexture, bounds.x(), bounds.y(),
+ m_drawingTexture, bounds.fLeft, bounds.fTop,
bounds.width(), bounds.height());
//TODO determine when drawing if the alpha value is used.
TilesManager::instance()->shader()->drawLayerQuad(drawTransform(), bounds,
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index d4510c5..fe41e35 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -47,6 +47,8 @@ class SkPicture;
namespace android {
class DrawExtra;
+void serializeLayer(LayerAndroid* layer, SkWStream* stream);
+LayerAndroid* deserializeLayer(SkStream* stream);
}
using namespace android;
@@ -256,6 +258,9 @@ public:
void setIsIframe(bool isIframe) { m_isIframe = isIframe; }
float zValue() const { return m_zValue; }
+ friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
+ friend LayerAndroid* android::deserializeLayer(SkStream* stream);
+
protected:
virtual void onDraw(SkCanvas*, SkScalar opacity);
@@ -269,6 +274,10 @@ private:
bool prepareContext(bool force = false);
void clipInner(SkTDArray<SkRect>* region, const SkRect& local) const;
+ // -------------------------------------------------------------------
+ // Fields to be serialized
+ // -------------------------------------------------------------------
+
bool m_haveClip;
bool m_isFixed;
bool m_backgroundColorSet;
@@ -284,13 +293,10 @@ private:
SkLength m_fixedMarginBottom;
SkRect m_fixedRect;
- SkPoint m_iframeOffset;
// When fixed element is undefined or auto, the render layer's position
// is needed for offset computation
IntPoint m_renderLayerPos;
- TransformationMatrix m_transform;
- float m_zValue;
bool m_backfaceVisibility;
bool m_visible;
@@ -299,9 +305,6 @@ private:
bool m_preserves3D;
float m_anchorPointZ;
float m_drawOpacity;
- TransformationMatrix m_drawTransform;
- TransformationMatrix m_childrenTransform;
- FloatRect m_clippingRect;
// Note that m_recordingPicture and m_contentsImage are mutually exclusive;
// m_recordingPicture is used when WebKit is asked to paint the layer's
@@ -315,6 +318,21 @@ private:
typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap;
KeyframesMap m_animations;
+
+ TransformationMatrix m_transform;
+ TransformationMatrix m_childrenTransform;
+
+ // -------------------------------------------------------------------
+ // Fields that are not serialized (generated, cached, or non-serializable)
+ // -------------------------------------------------------------------
+
+ SkPoint m_iframeOffset;
+
+ float m_zValue;
+
+ TransformationMatrix m_drawTransform;
+ FloatRect m_clippingRect;
+
SkPicture* m_extra;
int m_uniqueId;
diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
index b23f056..c3fdecd 100644
--- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h
@@ -57,6 +57,9 @@ public:
m_scrollLimits.set(x, y, x + width, y + height);
}
+ friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
+ friend LayerAndroid* android::deserializeLayer(SkStream* stream);
+
private:
SkRect m_scrollLimits;
};
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index c780e07..7ec77ed 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -27,15 +27,36 @@
#include "BaseLayerAndroid.h"
#include "CreateJavaOutputStreamAdaptor.h"
+#include "LayerAndroid.h"
#include "PictureSet.h"
+#include "ScrollableLayerAndroid.h"
+#include "SkLayer.h"
#include "SkPicture.h"
#include <JNIUtility.h>
#include <JNIHelp.h>
#include <jni.h>
+#ifdef DEBUG
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
namespace android {
+enum LayerTypes {
+ LTNone = 0,
+ LTLayerAndroid = 1,
+ LTScrollableLayerAndroid = 2,
+};
+
static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
jobject jstream, jbyteArray jstorage)
{
@@ -57,6 +78,13 @@ static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
if (!stream)
return false;
picture.serialize(stream);
+ int childCount = baseLayer->countChildren();
+ XLOG("BaseLayer has %d child(ren)", childCount);
+ stream->write32(childCount);
+ for (int i = 0; i < childCount; i++) {
+ LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i));
+ serializeLayer(layer, stream);
+ }
delete stream;
return true;
}
@@ -73,8 +101,306 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobjec
layer->setBackgroundColor(color);
#endif
SkPicture* picture = new SkPicture(stream);
- delete stream;
layer->setContent(picture);
+ SkSafeUnref(picture);
+ int childCount = stream->readS32();
+ for (int i = 0; i < childCount; i++) {
+ LayerAndroid* childLayer = deserializeLayer(stream);
+ if (childLayer)
+ layer->addChild(childLayer);
+ }
+ delete stream;
+ return layer;
+}
+
+// Serialization helpers
+
+void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
+{
+ for (int i = 0; i < 9; i++)
+ stream->writeScalar(matrix[i]);
+}
+
+SkMatrix readMatrix(SkStream *stream)
+{
+ SkMatrix matrix;
+ for (int i = 0; i < 9; i++)
+ matrix.set(i, stream->readScalar());
+ return matrix;
+}
+
+void writeSkLength(SkWStream *stream, SkLength length)
+{
+ stream->write32(length.type);
+ stream->writeScalar(length.value);
+}
+
+SkLength readSkLength(SkStream *stream)
+{
+ SkLength len;
+ len.type = (SkLength::SkLengthType) stream->readU32();
+ len.value = stream->readScalar();
+ return len;
+}
+
+void writeSkRect(SkWStream *stream, SkRect rect)
+{
+ stream->writeScalar(rect.fLeft);
+ stream->writeScalar(rect.fTop);
+ stream->writeScalar(rect.fRight);
+ stream->writeScalar(rect.fBottom);
+}
+
+SkRect readSkRect(SkStream *stream)
+{
+ SkRect rect;
+ rect.fLeft = stream->readScalar();
+ rect.fTop = stream->readScalar();
+ rect.fRight = stream->readScalar();
+ rect.fBottom = stream->readScalar();
+ return rect;
+}
+
+void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
+{
+ double value;
+ int dsize = sizeof(double);
+ value = matrix.m11();
+ stream->write(&value, dsize);
+ value = matrix.m12();
+ stream->write(&value, dsize);
+ value = matrix.m13();
+ stream->write(&value, dsize);
+ value = matrix.m14();
+ stream->write(&value, dsize);
+ value = matrix.m21();
+ stream->write(&value, dsize);
+ value = matrix.m22();
+ stream->write(&value, dsize);
+ value = matrix.m23();
+ stream->write(&value, dsize);
+ value = matrix.m24();
+ stream->write(&value, dsize);
+ value = matrix.m31();
+ stream->write(&value, dsize);
+ value = matrix.m32();
+ stream->write(&value, dsize);
+ value = matrix.m33();
+ stream->write(&value, dsize);
+ value = matrix.m34();
+ stream->write(&value, dsize);
+ value = matrix.m41();
+ stream->write(&value, dsize);
+ value = matrix.m42();
+ stream->write(&value, dsize);
+ value = matrix.m43();
+ stream->write(&value, dsize);
+ value = matrix.m44();
+ stream->write(&value, dsize);
+}
+
+void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
+{
+ double value;
+ int dsize = sizeof(double);
+ stream->read(&value, dsize);
+ matrix.setM11(value);
+ stream->read(&value, dsize);
+ matrix.setM12(value);
+ stream->read(&value, dsize);
+ matrix.setM13(value);
+ stream->read(&value, dsize);
+ matrix.setM14(value);
+ stream->read(&value, dsize);
+ matrix.setM21(value);
+ stream->read(&value, dsize);
+ matrix.setM22(value);
+ stream->read(&value, dsize);
+ matrix.setM23(value);
+ stream->read(&value, dsize);
+ matrix.setM24(value);
+ stream->read(&value, dsize);
+ matrix.setM31(value);
+ stream->read(&value, dsize);
+ matrix.setM32(value);
+ stream->read(&value, dsize);
+ matrix.setM33(value);
+ stream->read(&value, dsize);
+ matrix.setM34(value);
+ stream->read(&value, dsize);
+ matrix.setM41(value);
+ stream->read(&value, dsize);
+ matrix.setM42(value);
+ stream->read(&value, dsize);
+ matrix.setM43(value);
+ stream->read(&value, dsize);
+ matrix.setM44(value);
+}
+
+void serializeLayer(LayerAndroid* layer, SkWStream* stream)
+{
+ if (!layer) {
+ XLOG("NULL layer!");
+ stream->write8(LTNone);
+ return;
+ }
+ if (layer->isMedia() || layer->isVideo()) {
+ XLOG("Layer isn't supported for serialization: isMedia: %s, isVideo: %s",
+ layer->isMedia() ? "true" : "false",
+ layer->isVideo() ? "true" : "false");
+ stream->write8(LTNone);
+ return;
+ }
+ LayerTypes type = layer->contentIsScrollable()
+ ? LTScrollableLayerAndroid
+ : LTLayerAndroid;
+ stream->write8(type);
+
+ // Start with SkLayer fields
+ stream->writeBool(layer->isInheritFromRootTransform());
+ stream->writeScalar(layer->getOpacity());
+ stream->writeScalar(layer->getSize().width());
+ stream->writeScalar(layer->getSize().height());
+ stream->writeScalar(layer->getPosition().x());
+ stream->writeScalar(layer->getPosition().y());
+ stream->writeScalar(layer->getAnchorPoint().x());
+ stream->writeScalar(layer->getAnchorPoint().y());
+ writeMatrix(stream, layer->getMatrix());
+ writeMatrix(stream, layer->getChildrenMatrix());
+
+ // Next up, LayerAndroid fields
+ stream->writeBool(layer->m_haveClip);
+ stream->writeBool(layer->m_isFixed);
+ stream->writeBool(layer->m_backgroundColorSet);
+ stream->writeBool(layer->m_isIframe);
+ writeSkLength(stream, layer->m_fixedLeft);
+ writeSkLength(stream, layer->m_fixedTop);
+ writeSkLength(stream, layer->m_fixedRight);
+ writeSkLength(stream, layer->m_fixedBottom);
+ writeSkLength(stream, layer->m_fixedMarginLeft);
+ writeSkLength(stream, layer->m_fixedMarginTop);
+ writeSkLength(stream, layer->m_fixedMarginRight);
+ writeSkLength(stream, layer->m_fixedMarginBottom);
+ writeSkRect(stream, layer->m_fixedRect);
+ stream->write32(layer->m_renderLayerPos.x());
+ stream->write32(layer->m_renderLayerPos.y());
+ stream->writeBool(layer->m_backfaceVisibility);
+ stream->writeBool(layer->m_visible);
+ stream->write32(layer->m_backgroundColor);
+ stream->writeBool(layer->m_preserves3D);
+ stream->writeScalar(layer->m_anchorPointZ);
+ stream->writeScalar(layer->m_drawOpacity);
+ bool hasContentsImage = layer->m_contentsImage != 0;
+ stream->writeBool(hasContentsImage);
+ if (hasContentsImage) {
+ SkFlattenableWriteBuffer buffer(1024);
+ buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
+ layer->m_contentsImage->flatten(buffer);
+ stream->write32(buffer.size());
+ buffer.writeToStream(stream);
+ }
+ bool hasRecordingPicture = layer->m_recordingPicture != 0;
+ stream->writeBool(hasRecordingPicture);
+ if (hasRecordingPicture)
+ layer->m_recordingPicture->serialize(stream);
+ // TODO: support m_animations (maybe?)
+ stream->write32(0); // placeholder for m_animations.size();
+ writeTransformationMatrix(stream, layer->m_transform);
+ writeTransformationMatrix(stream, layer->m_childrenTransform);
+ if (type == LTScrollableLayerAndroid) {
+ ScrollableLayerAndroid* scrollableLayer =
+ static_cast<ScrollableLayerAndroid*>(layer);
+ stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft);
+ stream->writeScalar(scrollableLayer->m_scrollLimits.fTop);
+ stream->writeScalar(scrollableLayer->m_scrollLimits.width());
+ stream->writeScalar(scrollableLayer->m_scrollLimits.height());
+ }
+ int childCount = layer->countChildren();
+ stream->write32(childCount);
+ for (int i = 0; i < childCount; i++)
+ serializeLayer(layer->getChild(i), stream);
+}
+
+LayerAndroid* deserializeLayer(SkStream* stream)
+{
+ int type = stream->readU8();
+ if (type == LTNone)
+ return 0;
+ // Cast is to disambiguate between ctors.
+ LayerAndroid *layer;
+ if (type == LTLayerAndroid)
+ layer = new LayerAndroid((RenderLayer*) 0);
+ else if (type == LTScrollableLayerAndroid)
+ layer = new ScrollableLayerAndroid((RenderLayer*) 0);
+ else {
+ XLOG("Unexpected layer type: %d, aborting!", type);
+ return 0;
+ }
+
+ // SkLayer fields
+ layer->setInheritFromRootTransform(stream->readBool());
+ layer->setOpacity(stream->readScalar());
+ layer->setSize(stream->readScalar(), stream->readScalar());
+ layer->setPosition(stream->readScalar(), stream->readScalar());
+ layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
+ layer->setMatrix(readMatrix(stream));
+ layer->setChildrenMatrix(readMatrix(stream));
+
+ // LayerAndroid fields
+ layer->m_haveClip = stream->readBool();
+ layer->m_isFixed = stream->readBool();
+ layer->m_backgroundColorSet = stream->readBool();
+ layer->m_isIframe = stream->readBool();
+ layer->m_fixedLeft = readSkLength(stream);
+ layer->m_fixedTop = readSkLength(stream);
+ layer->m_fixedRight = readSkLength(stream);
+ layer->m_fixedBottom = readSkLength(stream);
+ layer->m_fixedMarginLeft = readSkLength(stream);
+ layer->m_fixedMarginTop = readSkLength(stream);
+ layer->m_fixedMarginRight = readSkLength(stream);
+ layer->m_fixedMarginBottom = readSkLength(stream);
+ layer->m_fixedRect = readSkRect(stream);
+ layer->m_renderLayerPos.setX(stream->readS32());
+ layer->m_renderLayerPos.setY(stream->readS32());
+ layer->m_backfaceVisibility = stream->readBool();
+ layer->m_visible = stream->readBool();
+ layer->m_backgroundColor = stream->readU32();
+ layer->m_preserves3D = stream->readBool();
+ layer->m_anchorPointZ = stream->readScalar();
+ layer->m_drawOpacity = stream->readScalar();
+ bool hasContentsImage = stream->readBool();
+ if (hasContentsImage) {
+ int size = stream->readU32();
+ SkAutoMalloc storage(size);
+ stream->read(storage.get(), size);
+ SkFlattenableReadBuffer buffer(storage.get(), size);
+ layer->m_contentsImage = new SkBitmap();
+ layer->m_contentsImage->unflatten(buffer);
+ }
+ bool hasRecordingPicture = stream->readBool();
+ if (hasRecordingPicture) {
+ layer->m_recordingPicture = new SkPicture(stream);
+ }
+ int animationCount = stream->readU32(); // TODO: Support (maybe?)
+ readTransformationMatrix(stream, layer->m_transform);
+ readTransformationMatrix(stream, layer->m_childrenTransform);
+ if (type == LTScrollableLayerAndroid) {
+ ScrollableLayerAndroid* scrollableLayer =
+ static_cast<ScrollableLayerAndroid*>(layer);
+ scrollableLayer->m_scrollLimits.set(
+ stream->readScalar(),
+ stream->readScalar(),
+ stream->readScalar(),
+ stream->readScalar());
+ }
+ int childCount = stream->readU32();
+ for (int i = 0; i < childCount; i++) {
+ LayerAndroid *childLayer = deserializeLayer(stream);
+ if (childLayer)
+ layer->addChild(childLayer);
+ }
+ layer->needsRepaint();
+ XLOG("Created layer with id %d", layer->uniqueId());
return layer;
}
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 8d3082b..61bc159 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -507,6 +507,11 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::In
SkRect visibleRect;
calcOurContentVisibleRect(&visibleRect);
+ // Make sure we have valid coordinates. We might not have valid coords
+ // if the zoom manager is still initializing. We will be redrawn
+ // once the correct scale is set
+ if (!visibleRect.hasValidCoordinates())
+ return false;
bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, invalRect,
webViewRect, titleBarHeight, clip, scale);
if (ret || m_glWebViewState->currentPictureCounter() != pic)