summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2012-03-06 14:14:00 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-03-06 14:14:00 -0800
commit221265b7850cf40a096dd513e2a492454405a6d0 (patch)
treee402fa1fb1aa19f22f5ae2f4ab9eb04a30ef1848 /Source
parentcc845c6b387500f968dea35d760d4a6bddae805a (diff)
parent74eee052852e8c1761c48ad2a44a4b394714b8cf (diff)
downloadexternal_webkit-221265b7850cf40a096dd513e2a492454405a6d0.zip
external_webkit-221265b7850cf40a096dd513e2a492454405a6d0.tar.gz
external_webkit-221265b7850cf40a096dd513e2a492454405a6d0.tar.bz2
Merge "Refactor LayerAndroid and add a FixedLayerAndroid class"
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/Android.mk2
-rw-r--r--Source/WebCore/platform/graphics/android/DumpLayer.cpp83
-rw-r--r--Source/WebCore/platform/graphics/android/DumpLayer.h67
-rw-r--r--Source/WebCore/platform/graphics/android/FixedLayerAndroid.cpp107
-rw-r--r--Source/WebCore/platform/graphics/android/FixedLayerAndroid.h122
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp15
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp238
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h111
-rw-r--r--Source/WebCore/platform/graphics/android/ScrollableLayerAndroid.h2
-rw-r--r--Source/WebKit/android/jni/ViewStateSerializer.cpp124
10 files changed, 562 insertions, 309 deletions
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 <wtf/CurrentTime.h>
+#include <cutils/log.h>
+#include <wtf/text/CString.h>
+#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<FixedLayerAndroid*>(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<SkRect>* 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<LayerGroup*>* 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<LayerAndroid*>(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<FixedLayerAndroid*>(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 },
};