From 74eee052852e8c1761c48ad2a44a4b394714b8cf Mon Sep 17 00:00:00 2001 From: Nicolas Roard Date: Mon, 5 Mar 2012 14:20:53 -0800 Subject: Refactor LayerAndroid and add a FixedLayerAndroid class Change-Id: Ic94e67678e7f5783bf6690308d0a13ce2202d1f2 --- Source/WebCore/Android.mk | 2 + .../platform/graphics/android/DumpLayer.cpp | 83 +++++++ .../WebCore/platform/graphics/android/DumpLayer.h | 67 ++++++ .../graphics/android/FixedLayerAndroid.cpp | 107 +++++++++ .../platform/graphics/android/FixedLayerAndroid.h | 122 +++++++++++ .../graphics/android/GraphicsLayerAndroid.cpp | 15 +- .../platform/graphics/android/LayerAndroid.cpp | 238 ++++----------------- .../platform/graphics/android/LayerAndroid.h | 111 +++------- .../graphics/android/ScrollableLayerAndroid.h | 2 +- Source/WebKit/android/jni/ViewStateSerializer.cpp | 124 ++++++++--- 10 files changed, 562 insertions(+), 309 deletions(-) create mode 100644 Source/WebCore/platform/graphics/android/DumpLayer.cpp create mode 100644 Source/WebCore/platform/graphics/android/DumpLayer.h create mode 100644 Source/WebCore/platform/graphics/android/FixedLayerAndroid.cpp create mode 100644 Source/WebCore/platform/graphics/android/FixedLayerAndroid.h diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index bae08c1..724ed4c 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -640,6 +640,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/BaseTileTexture.cpp \ platform/graphics/android/BitmapAllocatorAndroid.cpp \ platform/graphics/android/ClassTracker.cpp \ + platform/graphics/android/DumpLayer.cpp \ + platform/graphics/android/FixedLayerAndroid.cpp \ platform/graphics/android/FontAndroid.cpp \ platform/graphics/android/FontCacheAndroid.cpp \ platform/graphics/android/FontCustomPlatformData.cpp \ diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.cpp b/Source/WebCore/platform/graphics/android/DumpLayer.cpp new file mode 100644 index 0000000..5551965 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/DumpLayer.cpp @@ -0,0 +1,83 @@ +#include "config.h" +#include "DumpLayer.h" + +#if USE(ACCELERATED_COMPOSITING) + +namespace WebCore { + +void lwrite(FILE* file, const char* str) +{ + fwrite(str, sizeof(char), strlen(str), file); +} + +void writeIndent(FILE* file, int indentLevel) +{ + if (indentLevel) + fprintf(file, "%*s", indentLevel*2, " "); +} + +void writeln(FILE* file, int indentLevel, const char* str) +{ + writeIndent(file, indentLevel); + lwrite(file, str); + lwrite(file, "\n"); +} + +void writeIntVal(FILE* file, int indentLevel, const char* str, int value) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = %d;\n", str, value); +} + +void writeHexVal(FILE* file, int indentLevel, const char* str, int value) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = %x;\n", str, value); +} + +void writeFloatVal(FILE* file, int indentLevel, const char* str, float value) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = %.3f;\n", str, value); +} + +void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY); +} + +void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = { x = %d; y = %d; };\n", str, point.x(), point.y()); +} + +void writeSize(FILE* file, int indentLevel, const char* str, SkSize size) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height()); +} + +void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n", + str, rect.fLeft, rect.fTop, rect.width(), rect.height()); +} + +void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix) +{ + writeIndent(file, indentLevel); + fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f)," + "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n", + str, + matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(), + matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(), + matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(), + matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/DumpLayer.h b/Source/WebCore/platform/graphics/android/DumpLayer.h new file mode 100644 index 0000000..5b30952 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/DumpLayer.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DumpLayer_h +#define DumpLayer_h + +#include "IntPoint.h" +#include "SkPoint.h" +#include "SkRect.h" +#include "SkSize.h" +#include "TransformationMatrix.h" + +// Debug tools : dump the layers tree in a file. +// The format is simple: +// properties have the form: key = value; +// all statements are finished with a semi-colon. +// value can be: +// - int +// - float +// - array of elements +// - composed type +// a composed type enclose properties in { and } +// an array enclose composed types in { }, separated with a comma. +// exemple: +// { +// x = 3; +// y = 4; +// value = { +// x = 3; +// y = 4; +// }; +// anarray = [ +// { x = 3; }, +// { y = 4; } +// ]; +// } + +namespace WebCore { + +void lwrite(FILE* file, const char* str); +void writeIndent(FILE* file, int indentLevel); +void writeln(FILE* file, int indentLevel, const char* str); +void writeIntVal(FILE* file, int indentLevel, const char* str, int value); +void writeHexVal(FILE* file, int indentLevel, const char* str, int value); +void writeFloatVal(FILE* file, int indentLevel, const char* str, float value); +void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point); +void writeIntPoint(FILE* file, int indentLevel, const char* str, IntPoint point); +void writeSize(FILE* file, int indentLevel, const char* str, SkSize size); +void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect); +void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix); + +} + +#endif // DumpLayer_h diff --git a/Source/WebCore/platform/graphics/android/FixedLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/FixedLayerAndroid.cpp new file mode 100644 index 0000000..8642f8e --- /dev/null +++ b/Source/WebCore/platform/graphics/android/FixedLayerAndroid.cpp @@ -0,0 +1,107 @@ +#include "config.h" +#include "FixedLayerAndroid.h" +#include "DumpLayer.h" +#include "TilesManager.h" + +#include "GLWebViewState.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include +#include +#include +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "FixedLayerAndroid", __VA_ARGS__) + +namespace WebCore { + +FixedLayerAndroid::FixedLayerAndroid(const FixedLayerAndroid& layer) + : LayerAndroid(layer, LayerAndroid::FixedLayer) + , m_fixedLeft(layer.m_fixedLeft) + , m_fixedTop(layer.m_fixedTop) + , m_fixedRight(layer.m_fixedRight) + , m_fixedBottom(layer.m_fixedBottom) + , m_fixedMarginLeft(layer.m_fixedMarginLeft) + , m_fixedMarginTop(layer.m_fixedMarginTop) + , m_fixedMarginRight(layer.m_fixedMarginRight) + , m_fixedMarginBottom(layer.m_fixedMarginBottom) + , m_fixedRect(layer.m_fixedRect) + , m_renderLayerPos(layer.m_renderLayerPos) +{ +} + +LayerAndroid* FixedLayerAndroid::updateFixedLayerPosition(SkRect viewport, + LayerAndroid* parentIframeLayer) +{ + LayerAndroid* iframeLayer = LayerAndroid::updateFixedLayerPosition(viewport, parentIframeLayer); + + // So if this is a fixed layer inside a iframe, use the iframe offset + // and the iframe's size as the viewport and pass to the children + if (iframeLayer) { + viewport = SkRect::MakeXYWH(iframeLayer->iframeOffset().x(), + iframeLayer->iframeOffset().y(), + iframeLayer->getSize().width(), + iframeLayer->getSize().height()); + } + float w = viewport.width(); + float h = viewport.height(); + float dx = viewport.fLeft; + float dy = viewport.fTop; + float x = dx; + float y = dy; + + // It turns out that when it is 'auto', we should use the webkit value + // from the original render layer's X,Y, that will take care of alignment + // with the parent's layer and fix Margin etc. + if (!(m_fixedLeft.defined() || m_fixedRight.defined())) + x += m_renderLayerPos.x(); + else if (m_fixedLeft.defined() || !m_fixedRight.defined()) + x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft; + else + x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight; + + if (!(m_fixedTop.defined() || m_fixedBottom.defined())) + y += m_renderLayerPos.y(); + else if (m_fixedTop.defined() || !m_fixedBottom.defined()) + y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop; + else + y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom; + + this->setPosition(x, y); + + return iframeLayer; +} + +void FixedLayerAndroid::contentDraw(SkCanvas* canvas) +{ + LayerAndroid::contentDraw(canvas); + if (TilesManager::instance()->getShowVisualIndicator()) { + SkPaint paint; + paint.setARGB(80, 255, 0, 0); + canvas->drawRect(m_fixedRect, paint); + } +} + +void writeLength(FILE* file, int indentLevel, const char* str, SkLength length) +{ + if (!length.defined()) + return; + writeIndent(file, indentLevel); + fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value); +} + +void FixedLayerAndroid::dumpLayer(FILE* file, int indentLevel) const +{ + writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft); + writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop); + writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight); + writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom); + writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft); + writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop); + writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight); + writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom); + writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/FixedLayerAndroid.h b/Source/WebCore/platform/graphics/android/FixedLayerAndroid.h new file mode 100644 index 0000000..4f0f7c2 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/FixedLayerAndroid.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FixedLayerAndroid_h +#define FixedLayerAndroid_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerAndroid.h" + +namespace WebCore { + +struct SkLength { + enum SkLengthType { Undefined, Auto, Relative, + Percent, Fixed, Static, Intrinsic, MinIntrinsic }; + SkLengthType type; + SkScalar value; + SkLength() + { + type = Undefined; + value = 0; + } + bool defined() const + { + if (type == Undefined) + return false; + return true; + } + float calcFloatValue(float max) const + { + switch (type) { + case Percent: + return (max * value) / 100.0f; + case Fixed: + return value; + default: + return value; + } + } +}; + +class FixedLayerAndroid : public LayerAndroid { + +public: + FixedLayerAndroid(RenderLayer* owner) + : LayerAndroid(owner, LayerAndroid::FixedLayer) {} + FixedLayerAndroid(const LayerAndroid& layer) + : LayerAndroid(layer, LayerAndroid::FixedLayer) {} + FixedLayerAndroid(const FixedLayerAndroid& layer); + virtual ~FixedLayerAndroid() {}; + + virtual LayerAndroid* copy() const { return new FixedLayerAndroid(*this); } + + friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream); + friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream); + + virtual bool isFixed() const { return true; } + + void setFixedPosition(SkLength left, // CSS left property + SkLength top, // CSS top property + SkLength right, // CSS right property + SkLength bottom, // CSS bottom property + SkLength marginLeft, // CSS margin-left property + SkLength marginTop, // CSS margin-top property + SkLength marginRight, // CSS margin-right property + SkLength marginBottom, // CSS margin-bottom property + const IntPoint& renderLayerPos, // For undefined fixed position + SkRect viewRect) { // view rect, can be smaller than the layer's + m_fixedLeft = left; + m_fixedTop = top; + m_fixedRight = right; + m_fixedBottom = bottom; + m_fixedMarginLeft = marginLeft; + m_fixedMarginTop = marginTop; + m_fixedMarginRight = marginRight; + m_fixedMarginBottom = marginBottom; + m_fixedRect = viewRect; + m_renderLayerPos = renderLayerPos; + setShouldInheritFromRootTransform(true); + } + + virtual LayerAndroid* updateFixedLayerPosition(SkRect viewPort, + LayerAndroid* parentIframeLayer); + + virtual void contentDraw(SkCanvas*); + + virtual void dumpLayer(FILE*, int indentLevel) const; + +private: + SkLength m_fixedLeft; + SkLength m_fixedTop; + SkLength m_fixedRight; + SkLength m_fixedBottom; + SkLength m_fixedMarginLeft; + SkLength m_fixedMarginTop; + SkLength m_fixedMarginRight; + SkLength m_fixedMarginBottom; + SkRect m_fixedRect; + + // When fixed element is undefined or auto, the render layer's position + // is needed for offset computation + IntPoint m_renderLayerPos; +}; + +} + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif // FixedLayerAndroid_h diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index c50f6a6..80325e2 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -22,6 +22,7 @@ #include "AndroidAnimation.h" #include "Animation.h" #include "FloatRect.h" +#include "FixedLayerAndroid.h" #include "GraphicsContext.h" #include "Image.h" #include "ImagesManager.h" @@ -264,11 +265,23 @@ void GraphicsLayerAndroid::updateFixedPosition() SkRect viewRect; viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h); IntPoint renderLayerPos(renderLayer->x(), renderLayer->y()); - m_contentLayer->setFixedPosition(left, top, right, bottom, + + if (!m_contentLayer->isFixed()) { + FixedLayerAndroid* layer = new FixedLayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; + } + + FixedLayerAndroid* layer = static_cast(m_contentLayer); + layer->setFixedPosition(left, top, right, bottom, marginLeft, marginTop, marginRight, marginBottom, renderLayerPos, viewRect); + } else if (m_contentLayer->isFixed()) { + LayerAndroid* layer = new LayerAndroid(*m_contentLayer); + m_contentLayer->unref(); + m_contentLayer = layer; } } diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 67d3dd3..e3c3b04 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -6,6 +6,7 @@ #include "AndroidAnimation.h" #include "ClassTracker.h" #include "DrawExtra.h" +#include "DumpLayer.h" #include "GLUtils.h" #include "ImagesManager.h" #include "InspectorCanvas.h" @@ -57,9 +58,8 @@ private: /////////////////////////////////////////////////////////////////////////////// -LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), +LayerAndroid::LayerAndroid(RenderLayer* owner, SubclassType subclassType) : Layer(), m_haveClip(false), - m_isFixed(false), m_isIframe(false), m_backfaceVisibility(true), m_visible(true), @@ -74,13 +74,13 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_lastComputeTextureSize(0), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), + m_subclassType(subclassType), m_hasText(true), m_layerGroup(0) { m_backgroundColor = 0; m_preserves3D = false; - m_iframeOffset.set(0,0); m_dirtyRegion.setEmpty(); #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid"); @@ -88,7 +88,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), #endif } -LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), +LayerAndroid::LayerAndroid(const LayerAndroid& layer, SubclassType subclassType) : Layer(layer), m_haveClip(layer.m_haveClip), m_isIframe(layer.m_isIframe), m_zValue(layer.m_zValue), @@ -98,26 +98,20 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_hasText(true), m_layerGroup(0) { - m_isFixed = layer.m_isFixed; 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; m_visible = layer.m_visible; m_backgroundColor = layer.m_backgroundColor; - m_fixedLeft = layer.m_fixedLeft; - m_fixedTop = layer.m_fixedTop; - m_fixedRight = layer.m_fixedRight; - m_fixedBottom = layer.m_fixedBottom; - m_fixedMarginLeft = layer.m_fixedMarginLeft; - m_fixedMarginTop = layer.m_fixedMarginTop; - m_fixedMarginRight = layer.m_fixedMarginRight; - m_fixedMarginBottom = layer.m_fixedMarginBottom; - m_fixedRect = layer.m_fixedRect; + if (subclassType == LayerAndroid::CopyLayer) + m_subclassType = layer.m_subclassType; + else + m_subclassType = subclassType; + m_iframeOffset = layer.m_iframeOffset; m_offset = layer.m_offset; m_iframeScrollOffset = layer.m_iframeScrollOffset; @@ -174,7 +168,6 @@ void LayerAndroid::checkForPictureOptimizations() LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_haveClip(false), - m_isFixed(false), m_isIframe(false), m_recordingPicture(picture), m_zValue(0), @@ -184,12 +177,12 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_lastComputeTextureSize(0), m_owningLayer(0), m_type(LayerAndroid::NavCacheLayer), + m_subclassType(LayerAndroid::StandardLayer), m_hasText(true), m_layerGroup(0) { m_backgroundColor = 0; SkSafeRef(m_recordingPicture); - m_iframeOffset.set(0,0); m_dirtyRegion.setEmpty(); #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid - from picture"); @@ -389,74 +382,46 @@ void LayerAndroid::clipInner(SkTDArray* region, getChild(i)->clipInner(region, m_haveClip ? localBounds : local); } -bool LayerAndroid::updateFixedLayersPositions(SkRect viewport, LayerAndroid* parentIframeLayer) +LayerAndroid* LayerAndroid::updateFixedLayerPosition(SkRect viewport, + LayerAndroid* parentIframeLayer) { - bool hasFixedElements = false; - XLOG("updating fixed positions, using viewport %fx%f - %fx%f", - viewport.fLeft, viewport.fTop, - viewport.width(), viewport.height()); + LayerAndroid* iframe = parentIframeLayer; + // If this is an iframe, accumulate the offset from the parent with // current position, and change the parent pointer. if (m_isIframe) { // If this is the top level, take the current position SkPoint parentOffset; parentOffset.set(0,0); - if (parentIframeLayer) - parentOffset = parentIframeLayer->getPosition(); + if (iframe) + parentOffset = iframe->getPosition(); - m_iframeOffset = parentOffset + getPosition(); + SkPoint offset = parentOffset + getPosition(); + m_iframeOffset = IntPoint(offset.fX, offset.fY); - parentIframeLayer = this; + iframe = this; } - if (m_isFixed) { - hasFixedElements = true; - // So if this is a fixed layer inside a iframe, use the iframe offset - // and the iframe's size as the viewport and pass to the children - if (parentIframeLayer) { - viewport = SkRect::MakeXYWH(parentIframeLayer->m_iframeOffset.fX, - parentIframeLayer->m_iframeOffset.fY, - parentIframeLayer->getSize().width(), - parentIframeLayer->getSize().height()); - } - float w = viewport.width(); - float h = viewport.height(); - float dx = viewport.fLeft; - float dy = viewport.fTop; - float x = dx; - float y = dy; - - // It turns out that when it is 'auto', we should use the webkit value - // from the original render layer's X,Y, that will take care of alignment - // with the parent's layer and fix Margin etc. - if (!(m_fixedLeft.defined() || m_fixedRight.defined())) - x += m_renderLayerPos.x(); - else if (m_fixedLeft.defined() || !m_fixedRight.defined()) - x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft; - else - x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight; - - if (!(m_fixedTop.defined() || m_fixedBottom.defined())) - y += m_renderLayerPos.y(); - else if (m_fixedTop.defined() || !m_fixedBottom.defined()) - y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop; - else - y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom; - - this->setPosition(x, y); - } + return iframe; +} + +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()); + + LayerAndroid* iframeLayer = updateFixedLayerPosition(viewport, parentIframeLayer); int count = this->countChildren(); for (int i = 0; i < count; i++) - hasFixedElements |= this->getChild(i)->updateFixedLayersPositions(viewport, parentIframeLayer); - - return hasFixedElements; + this->getChild(i)->updateFixedLayersPositions(viewport, iframeLayer); } void LayerAndroid::updatePositions() { // apply the viewport to us - if (!m_isFixed) { + if (!isFixed()) { // turn our fields into a matrix. // // FIXME: this should happen in the caller, and we should remove these @@ -482,7 +447,7 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM float originX = anchorPoint.x() * layerSize.width(); float originY = anchorPoint.y() * layerSize.height(); TransformationMatrix localMatrix; - if (!m_isFixed) + if (!isFixed()) localMatrix = parentMatrix; localMatrix.translate3d(originX + position.x(), originY + position.y(), @@ -635,9 +600,9 @@ 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 %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " + XLOGC("%s %s (%d) [%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, + spaces, subclassName().latin1().data(), m_subclassType, uniqueId(), m_owningLayer, needsTexture() ? "needs a texture" : "no texture", m_imageCRC ? "has an image" : "no image", tr.x(), tr.y(), tr.width(), tr.height(), @@ -753,7 +718,7 @@ void LayerAndroid::assignGroups(Vector* allGroups) currentLayerGroup = allGroups->at(0); // TODO: compare layer with group on top of stack - fixed? overscroll? transformed? - needsIsolation = m_isFixed || (m_animations.size() != 0); + needsIsolation = isFixed() || (m_animations.size() != 0); if (!currentLayerGroup || needsIsolation || true) { currentLayerGroup = new LayerGroup(); @@ -915,12 +880,6 @@ void LayerAndroid::contentDraw(SkCanvas* canvas) canvas->drawLine(0, h, w, h, paint); canvas->drawLine(w, h, w, 0, paint); canvas->drawLine(w, 0, 0, 0, paint); - - if (m_isFixed) { - SkPaint paint; - paint.setARGB(80, 255, 0, 0); - canvas->drawRect(m_fixedRect, paint); - } } } @@ -1018,116 +977,14 @@ SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const return result; } -// Debug tools : dump the layers tree in a file. -// The format is simple: -// properties have the form: key = value; -// all statements are finished with a semi-colon. -// value can be: -// - int -// - float -// - array of elements -// - composed type -// a composed type enclose properties in { and } -// an array enclose composed types in { }, separated with a comma. -// exemple: -// { -// x = 3; -// y = 4; -// value = { -// x = 3; -// y = 4; -// }; -// anarray = [ -// { x = 3; }, -// { y = 4; } -// ]; -// } - -void lwrite(FILE* file, const char* str) -{ - fwrite(str, sizeof(char), strlen(str), file); -} - -void writeIndent(FILE* file, int indentLevel) -{ - if (indentLevel) - fprintf(file, "%*s", indentLevel*2, " "); -} - -void writeln(FILE* file, int indentLevel, const char* str) -{ - writeIndent(file, indentLevel); - lwrite(file, str); - lwrite(file, "\n"); -} - -void writeIntVal(FILE* file, int indentLevel, const char* str, int value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %d;\n", str, value); -} - -void writeHexVal(FILE* file, int indentLevel, const char* str, int value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %x;\n", str, value); -} - -void writeFloatVal(FILE* file, int indentLevel, const char* str, float value) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = %.3f;\n", str, value); -} - -void writePoint(FILE* file, int indentLevel, const char* str, SkPoint point) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { x = %.3f; y = %.3f; };\n", str, point.fX, point.fY); -} - -void writeSize(FILE* file, int indentLevel, const char* str, SkSize size) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height()); -} - -void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n", - str, rect.fLeft, rect.fTop, rect.width(), rect.height()); -} - -void writeLength(FILE* file, int indentLevel, const char* str, SkLength length) +void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const { - if (!length.defined()) - return; - writeIndent(file, indentLevel); - fprintf(file, "%s = { type = %d; value = %.2f; };\n", str, length.type, length.value); -} - -void writeMatrix(FILE* file, int indentLevel, const char* str, const TransformationMatrix& matrix) -{ - writeIndent(file, indentLevel); - fprintf(file, "%s = { (%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f)," - "(%.2f,%.2f,%.2f,%.2f),(%.2f,%.2f,%.2f,%.2f) };\n", - str, - matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(), - matrix.m21(), matrix.m22(), matrix.m23(), matrix.m24(), - matrix.m31(), matrix.m32(), matrix.m33(), matrix.m34(), - matrix.m41(), matrix.m42(), matrix.m43(), matrix.m44()); -} - -void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const -{ - writeln(file, indentLevel, "{"); - writeHexVal(file, indentLevel + 1, "layer", (int)this); writeIntVal(file, indentLevel + 1, "layerId", m_uniqueId); writeIntVal(file, indentLevel + 1, "haveClip", m_haveClip); - writeIntVal(file, indentLevel + 1, "isFixed", m_isFixed); + writeIntVal(file, indentLevel + 1, "isFixed", isFixed()); writeIntVal(file, indentLevel + 1, "m_isIframe", m_isIframe); - writePoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset); + writeIntPoint(file, indentLevel + 1, "m_iframeOffset", m_iframeOffset); writeFloatVal(file, indentLevel + 1, "opacity", getOpacity()); writeSize(file, indentLevel + 1, "size", getSize()); @@ -1138,22 +995,17 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform); writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect)); - if (m_isFixed) { - writeLength(file, indentLevel + 1, "fixedLeft", m_fixedLeft); - writeLength(file, indentLevel + 1, "fixedTop", m_fixedTop); - writeLength(file, indentLevel + 1, "fixedRight", m_fixedRight); - writeLength(file, indentLevel + 1, "fixedBottom", m_fixedBottom); - writeLength(file, indentLevel + 1, "fixedMarginLeft", m_fixedMarginLeft); - writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop); - writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight); - writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom); - writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect); - } - if (m_recordingPicture) { writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width()); writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height()); } +} + +void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const +{ + writeln(file, indentLevel, "{"); + + dumpLayer(file, indentLevel); if (countChildren()) { writeln(file, indentLevel + 1, "children = ["); diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index 86d27bc..62fc863 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -55,40 +55,12 @@ class ImageTexture; namespace android { class DrawExtra; void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream); -WebCore::LayerAndroid* deserializeLayer(SkStream* stream); +WebCore::LayerAndroid* deserializeLayer(int version, SkStream* stream); void cleanupImageRefs(WebCore::LayerAndroid* layer); } using namespace android; -struct SkLength { - enum SkLengthType { Undefined, Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; - SkLengthType type; - SkScalar value; - SkLength() - { - type = Undefined; - value = 0; - } - bool defined() const - { - if (type == Undefined) - return false; - return true; - } - float calcFloatValue(float max) const - { - switch (type) { - case Percent: - return (max * value) / 100.0f; - case Fixed: - return value; - default: - return value; - } - } -}; - namespace WebCore { class AndroidAnimation; @@ -115,10 +87,24 @@ public: class TEST_EXPORT LayerAndroid : public Layer { public: - enum LayerType { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer }; + typedef enum { UndefinedLayer, WebCoreLayer, UILayer, NavCacheLayer } LayerType; + typedef enum { StandardLayer, CopyLayer, FixedLayer } SubclassType; - LayerAndroid(RenderLayer* owner); - LayerAndroid(const LayerAndroid& layer); + String subclassName() + { + switch (m_subclassType) { + case LayerAndroid::StandardLayer: + return "StandardLayer"; + case LayerAndroid::CopyLayer: + return "CopyLayer"; + case LayerAndroid::FixedLayer: + return "FixedLayer"; + } + return "Undefined"; + } + + LayerAndroid(RenderLayer* owner, SubclassType type = LayerAndroid::StandardLayer); + LayerAndroid(const LayerAndroid& layer, SubclassType type = LayerAndroid::CopyLayer); LayerAndroid(SkPicture*); virtual ~LayerAndroid(); @@ -168,31 +154,8 @@ public: void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; } const FloatRect& drawClip() { return m_clippingRect; } - void setFixedPosition(SkLength left, // CSS left property - SkLength top, // CSS top property - SkLength right, // CSS right property - SkLength bottom, // CSS bottom property - SkLength marginLeft, // CSS margin-left property - SkLength marginTop, // CSS margin-top property - SkLength marginRight, // CSS margin-right property - SkLength marginBottom, // CSS margin-bottom property - const IntPoint& renderLayerPos, // For undefined fixed position - SkRect viewRect) { // view rect, can be smaller than the layer's - m_fixedLeft = left; - m_fixedTop = top; - m_fixedRight = right; - m_fixedBottom = bottom; - m_fixedMarginLeft = marginLeft; - m_fixedMarginTop = marginTop; - m_fixedMarginRight = marginRight; - m_fixedMarginBottom = marginBottom; - m_fixedRect = viewRect; - m_isFixed = true; - m_renderLayerPos = renderLayerPos; - setShouldInheritFromRootTransform(true); - } - const IntPoint& scrollOffset() const { return m_offset; } + const IntPoint& iframeOffset() const { return m_iframeOffset; } const IntPoint& iframeScrollOffset() const { return m_iframeScrollOffset; } void setScrollOffset(IntPoint offset) { m_offset = offset; } void setIFrameScrollOffset(IntPoint offset) { m_iframeScrollOffset = offset; } @@ -222,6 +185,7 @@ public: // in global space. SkRect subtractLayers(const SkRect&) const; + virtual void dumpLayer(FILE*, int indentLevel) const; void dumpLayers(FILE*, int indentLevel) const; void dumpToLog() const; @@ -231,7 +195,9 @@ public: This call is recursive, so it should be called on the root of the hierarchy. */ - bool updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0); + void updateFixedLayersPositions(SkRect viewPort, LayerAndroid* parentIframeLayer = 0); + virtual LayerAndroid* updateFixedLayerPosition(SkRect viewport, + LayerAndroid* parentIframeLayer); /** Call this to update the position attribute, so that later calls like bounds() will report the corrected position. @@ -253,7 +219,6 @@ public: return static_cast(this->INHERITED::getChild(index)); } int uniqueId() const { return m_uniqueId; } - bool isFixed() { return m_isFixed; } /** This sets a content image -- calling it means we will use the image directly when drawing the layer instead of using @@ -272,10 +237,11 @@ public: void clearDirtyRegion(); - void contentDraw(SkCanvas*); + virtual void contentDraw(SkCanvas*); virtual bool isMedia() const { return false; } virtual bool isVideo() const { return false; } + virtual bool isFixed() const { return false; } RenderLayer* owningLayer() const { return m_owningLayer; } @@ -285,7 +251,7 @@ public: // ViewStateSerializer friends friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream); - friend LayerAndroid* android::deserializeLayer(SkStream* stream); + friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream); friend void android::cleanupImageRefs(LayerAndroid* layer); void obtainTextureForPainting(LayerAndroid* drawingLayer); @@ -296,7 +262,8 @@ public: bool updateWithTree(LayerAndroid*); virtual bool updateWithLayer(LayerAndroid*); - int type() { return m_type; } + LayerType type() { return m_type; } + SubclassType subclassType() { return m_subclassType; } bool hasText() { return m_hasText; } void checkForPictureOptimizations(); @@ -312,7 +279,9 @@ public: protected: virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra); + IntPoint m_offset; + IntPoint m_iframeOffset; IntPoint m_iframeScrollOffset; TransformationMatrix m_drawTransform; @@ -330,24 +299,9 @@ private: // ------------------------------------------------------------------- bool m_haveClip; - bool m_isFixed; bool m_backgroundColorSet; bool m_isIframe; - SkLength m_fixedLeft; - SkLength m_fixedTop; - SkLength m_fixedRight; - SkLength m_fixedBottom; - SkLength m_fixedMarginLeft; - SkLength m_fixedMarginTop; - SkLength m_fixedMarginRight; - SkLength m_fixedMarginBottom; - SkRect m_fixedRect; - - // When fixed element is undefined or auto, the render layer's position - // is needed for offset computation - IntPoint m_renderLayerPos; - bool m_backfaceVisibility; bool m_visible; @@ -375,8 +329,6 @@ private: // Fields that are not serialized (generated, cached, or non-serializable) // ------------------------------------------------------------------- - SkPoint m_iframeOffset; - float m_zValue; FloatRect m_clippingRect; @@ -403,7 +355,8 @@ private: RenderLayer* m_owningLayer; - int m_type; + LayerType m_type; + SubclassType m_subclassType; bool m_hasText; diff --git a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h index b8ff299..824804f 100644 --- a/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h @@ -68,7 +68,7 @@ public: bool scrollRectIntoView(const SkIRect&); friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream); - friend LayerAndroid* android::deserializeLayer(SkStream* stream); + friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream); private: diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp index 6b473f5..78a3543 100644 --- a/Source/WebKit/android/jni/ViewStateSerializer.cpp +++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp @@ -27,6 +27,7 @@ #include "BaseLayerAndroid.h" #include "CreateJavaOutputStreamAdaptor.h" +#include "FixedLayerAndroid.h" #include "ImagesManager.h" #include "Layer.h" #include "LayerAndroid.h" @@ -49,6 +50,9 @@ #undef XLOG #define XLOG(...) +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__) + #endif // DEBUG namespace android { @@ -57,6 +61,7 @@ enum LayerTypes { LTNone = 0, LTLayerAndroid = 1, LTScrollableLayerAndroid = 2, + LTFixedLayerAndroid = 3 }; static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, @@ -91,8 +96,8 @@ static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, return true; } -static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobject jstream, - jbyteArray jstorage) +static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version, + jobject jstream, jbyteArray jstorage) { SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage); if (!stream) @@ -107,7 +112,7 @@ static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobjec SkSafeUnref(picture); int childCount = stream->readS32(); for (int i = 0; i < childCount; i++) { - LayerAndroid* childLayer = deserializeLayer(stream); + LayerAndroid* childLayer = deserializeLayer(version, stream); if (childLayer) layer->addChild(childLayer); } @@ -253,9 +258,9 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream) stream->write8(LTNone); return; } - LayerTypes type = layer->contentIsScrollable() - ? LTScrollableLayerAndroid - : LTLayerAndroid; + LayerTypes type = LTLayerAndroid; + if (layer->contentIsScrollable()) + type = LTScrollableLayerAndroid; stream->write8(type); // Start with Layer fields @@ -272,20 +277,43 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream) // Next up, LayerAndroid fields stream->writeBool(layer->m_haveClip); - stream->writeBool(layer->m_isFixed); + stream->writeBool(layer->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()); + + // With the current LayerAndroid hierarchy, LayerAndroid doesn't have + // those fields anymore. Let's keep the current serialization format for + // now and output blank fields... not great, but probably better than + // dealing with multiple versions. + if (layer->isFixed()) { + FixedLayerAndroid* fixedLayer = static_cast(layer); + writeSkLength(stream, fixedLayer->m_fixedLeft); + writeSkLength(stream, fixedLayer->m_fixedTop); + writeSkLength(stream, fixedLayer->m_fixedRight); + writeSkLength(stream, fixedLayer->m_fixedBottom); + writeSkLength(stream, fixedLayer->m_fixedMarginLeft); + writeSkLength(stream, fixedLayer->m_fixedMarginTop); + writeSkLength(stream, fixedLayer->m_fixedMarginRight); + writeSkLength(stream, fixedLayer->m_fixedMarginBottom); + writeSkRect(stream, fixedLayer->m_fixedRect); + stream->write32(fixedLayer->m_renderLayerPos.x()); + stream->write32(fixedLayer->m_renderLayerPos.y()); + } else { + SkLength length; + SkRect rect; + writeSkLength(stream, length); // fixedLeft + writeSkLength(stream, length); // fixedTop + writeSkLength(stream, length); // fixedRight + writeSkLength(stream, length); // fixedBottom + writeSkLength(stream, length); // fixedMarginLeft + writeSkLength(stream, length); // fixedMarginTop + writeSkLength(stream, length); // fixedMarginRight + writeSkLength(stream, length); // fixedMarginBottom + writeSkRect(stream, rect); // fixedRect + stream->write32(0); // renderLayerPos.x() + stream->write32(0); // renderLayerPos.y() + } + stream->writeBool(layer->m_backfaceVisibility); stream->writeBool(layer->m_visible); stream->write32(layer->m_backgroundColor); @@ -327,7 +355,7 @@ void serializeLayer(LayerAndroid* layer, SkWStream* stream) serializeLayer(layer->getChild(i), stream); } -LayerAndroid* deserializeLayer(SkStream* stream) +LayerAndroid* deserializeLayer(int version, SkStream* stream) { int type = stream->readU8(); if (type == LTNone) @@ -354,20 +382,46 @@ LayerAndroid* deserializeLayer(SkStream* 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()); + + // Keep the legacy serialization/deserialization format... + bool isFixed = stream->readBool(); + if (isFixed) { + FixedLayerAndroid* fixedLayer = new FixedLayerAndroid(*layer); + layer->unref(); + layer = fixedLayer; + + layer->m_backgroundColorSet = stream->readBool(); + layer->m_isIframe = stream->readBool(); + + fixedLayer->m_fixedLeft = readSkLength(stream); + fixedLayer->m_fixedTop = readSkLength(stream); + fixedLayer->m_fixedRight = readSkLength(stream); + fixedLayer->m_fixedBottom = readSkLength(stream); + fixedLayer->m_fixedMarginLeft = readSkLength(stream); + fixedLayer->m_fixedMarginTop = readSkLength(stream); + fixedLayer->m_fixedMarginRight = readSkLength(stream); + fixedLayer->m_fixedMarginBottom = readSkLength(stream); + fixedLayer->m_fixedRect = readSkRect(stream); + fixedLayer->m_renderLayerPos.setX(stream->readS32()); + fixedLayer->m_renderLayerPos.setY(stream->readS32()); + } else { + layer->m_backgroundColorSet = stream->readBool(); + layer->m_isIframe = stream->readBool(); + + // Not a fixed element, bypass the values in the stream + readSkLength(stream); // fixedLeft + readSkLength(stream); // fixedTop + readSkLength(stream); // fixedRight + readSkLength(stream); // fixedBottom + readSkLength(stream); // fixedMarginLeft + readSkLength(stream); // fixedMarginTop + readSkLength(stream); // fixedMarginRight + readSkLength(stream); // fixedMarginBottom + readSkRect(stream); // fixedRect + stream->readS32(); // renderLayerPos.x() + stream->readS32(); // renderLayerPos.y() + } + layer->m_backfaceVisibility = stream->readBool(); layer->m_visible = stream->readBool(); layer->m_backgroundColor = stream->readU32(); @@ -404,7 +458,7 @@ LayerAndroid* deserializeLayer(SkStream* stream) } int childCount = stream->readU32(); for (int i = 0; i < childCount; i++) { - LayerAndroid *childLayer = deserializeLayer(stream); + LayerAndroid *childLayer = deserializeLayer(version, stream); if (childLayer) layer->addChild(childLayer); } @@ -419,7 +473,7 @@ LayerAndroid* deserializeLayer(SkStream* stream) static JNINativeMethod gSerializerMethods[] = { { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z", (void*) nativeSerializeViewState }, - { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I", + { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I", (void*) nativeDeserializeViewState }, }; -- cgit v1.1