diff options
author | John Reck <jreck@google.com> | 2011-06-06 17:31:38 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2011-06-07 13:40:23 -0700 |
commit | d68563709fdf68c90c730155149f6149b084730a (patch) | |
tree | 9ed48c92bbaff2f66fcc6778b9b650134bc68bc6 /Source/WebKit/android | |
parent | dfadaafc15c16563aba837f05c778eaa2a433a8b (diff) | |
download | external_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
Diffstat (limited to 'Source/WebKit/android')
-rw-r--r-- | Source/WebKit/android/jni/ViewStateSerializer.cpp | 328 | ||||
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 5 |
2 files changed, 332 insertions, 1 deletions
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) |