diff options
author | John Reck <jreck@google.com> | 2011-06-08 08:58:28 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-08 08:58:28 -0700 |
commit | 12b73c856f825f0819e61834cb0bc76353b261d4 (patch) | |
tree | be49c2d8f2c7753d7f91a2823e156a8194bfa974 | |
parent | 3742ac093d35d923c81693096ab6671e9b147700 (diff) | |
parent | d68563709fdf68c90c730155149f6149b084730a (diff) | |
download | external_webkit-12b73c856f825f0819e61834cb0bc76353b261d4.zip external_webkit-12b73c856f825f0819e61834cb0bc76353b261d4.tar.gz external_webkit-12b73c856f825f0819e61834cb0bc76353b261d4.tar.bz2 |
Merge "Serialize LayerAndroid"
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) |