OSDN Git Service

794c118b9ae94b846765161481564e1a079c224d
[android-x86/external-webkit.git] / Source / WebKit / android / jni / ViewStateSerializer.cpp
1 /*
2  * Copyright 2011, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include "BaseLayerAndroid.h"
29 #include "CreateJavaOutputStreamAdaptor.h"
30 #include "Layer.h"
31 #include "LayerAndroid.h"
32 #include "PictureSet.h"
33 #include "ScrollableLayerAndroid.h"
34 #include "SkPicture.h"
35
36 #include <JNIUtility.h>
37 #include <JNIHelp.h>
38 #include <jni.h>
39
40 #ifdef DEBUG
41
42 #undef XLOG
43 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__)
44
45 #else
46
47 #undef XLOG
48 #define XLOG(...)
49
50 #endif // DEBUG
51
52 namespace android {
53
54 enum LayerTypes {
55     LTNone = 0,
56     LTLayerAndroid = 1,
57     LTScrollableLayerAndroid = 2,
58 };
59
60 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
61                                      jobject jstream, jbyteArray jstorage)
62 {
63     BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer;
64     if (!baseLayer)
65         return false;
66
67     SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
68 #if USE(ACCELERATED_COMPOSITING)
69     stream->write32(baseLayer->getBackgroundColor().rgb());
70 #else
71     stream->write32(0);
72 #endif
73     SkPicture picture;
74     PictureSet* content = baseLayer->content();
75     baseLayer->drawCanvas(picture.beginRecording(content->width(), content->height(),
76             SkPicture::kUsePathBoundsForClip_RecordingFlag));
77     picture.endRecording();
78     if (!stream)
79         return false;
80     picture.serialize(stream);
81     int childCount = baseLayer->countChildren();
82     XLOG("BaseLayer has %d child(ren)", childCount);
83     stream->write32(childCount);
84     for (int i = 0; i < childCount; i++) {
85         LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i));
86         serializeLayer(layer, stream);
87     }
88     delete stream;
89     return true;
90 }
91
92 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobject jstream,
93                                       jbyteArray jstorage)
94 {
95     SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
96     if (!stream)
97         return 0;
98     BaseLayerAndroid* layer = new BaseLayerAndroid();
99     Color color = stream->readU32();
100 #if USE(ACCELERATED_COMPOSITING)
101     layer->setBackgroundColor(color);
102 #endif
103     SkPicture* picture = new SkPicture(stream);
104     layer->setContent(picture);
105     SkSafeUnref(picture);
106     int childCount = stream->readS32();
107     for (int i = 0; i < childCount; i++) {
108         LayerAndroid* childLayer = deserializeLayer(stream);
109         if (childLayer)
110             layer->addChild(childLayer);
111     }
112     delete stream;
113     return layer;
114 }
115
116 // Serialization helpers
117
118 void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
119 {
120     for (int i = 0; i < 9; i++)
121         stream->writeScalar(matrix[i]);
122 }
123
124 SkMatrix readMatrix(SkStream *stream)
125 {
126     SkMatrix matrix;
127     for (int i = 0; i < 9; i++)
128         matrix.set(i, stream->readScalar());
129     return matrix;
130 }
131
132 void writeSkLength(SkWStream *stream, SkLength length)
133 {
134     stream->write32(length.type);
135     stream->writeScalar(length.value);
136 }
137
138 SkLength readSkLength(SkStream *stream)
139 {
140     SkLength len;
141     len.type = (SkLength::SkLengthType) stream->readU32();
142     len.value = stream->readScalar();
143     return len;
144 }
145
146 void writeSkRect(SkWStream *stream, SkRect rect)
147 {
148     stream->writeScalar(rect.fLeft);
149     stream->writeScalar(rect.fTop);
150     stream->writeScalar(rect.fRight);
151     stream->writeScalar(rect.fBottom);
152 }
153
154 SkRect readSkRect(SkStream *stream)
155 {
156     SkRect rect;
157     rect.fLeft = stream->readScalar();
158     rect.fTop = stream->readScalar();
159     rect.fRight = stream->readScalar();
160     rect.fBottom = stream->readScalar();
161     return rect;
162 }
163
164 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
165 {
166     double value;
167     int dsize = sizeof(double);
168     value = matrix.m11();
169     stream->write(&value, dsize);
170     value = matrix.m12();
171     stream->write(&value, dsize);
172     value = matrix.m13();
173     stream->write(&value, dsize);
174     value = matrix.m14();
175     stream->write(&value, dsize);
176     value = matrix.m21();
177     stream->write(&value, dsize);
178     value = matrix.m22();
179     stream->write(&value, dsize);
180     value = matrix.m23();
181     stream->write(&value, dsize);
182     value = matrix.m24();
183     stream->write(&value, dsize);
184     value = matrix.m31();
185     stream->write(&value, dsize);
186     value = matrix.m32();
187     stream->write(&value, dsize);
188     value = matrix.m33();
189     stream->write(&value, dsize);
190     value = matrix.m34();
191     stream->write(&value, dsize);
192     value = matrix.m41();
193     stream->write(&value, dsize);
194     value = matrix.m42();
195     stream->write(&value, dsize);
196     value = matrix.m43();
197     stream->write(&value, dsize);
198     value = matrix.m44();
199     stream->write(&value, dsize);
200 }
201
202 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
203 {
204     double value;
205     int dsize = sizeof(double);
206     stream->read(&value, dsize);
207     matrix.setM11(value);
208     stream->read(&value, dsize);
209     matrix.setM12(value);
210     stream->read(&value, dsize);
211     matrix.setM13(value);
212     stream->read(&value, dsize);
213     matrix.setM14(value);
214     stream->read(&value, dsize);
215     matrix.setM21(value);
216     stream->read(&value, dsize);
217     matrix.setM22(value);
218     stream->read(&value, dsize);
219     matrix.setM23(value);
220     stream->read(&value, dsize);
221     matrix.setM24(value);
222     stream->read(&value, dsize);
223     matrix.setM31(value);
224     stream->read(&value, dsize);
225     matrix.setM32(value);
226     stream->read(&value, dsize);
227     matrix.setM33(value);
228     stream->read(&value, dsize);
229     matrix.setM34(value);
230     stream->read(&value, dsize);
231     matrix.setM41(value);
232     stream->read(&value, dsize);
233     matrix.setM42(value);
234     stream->read(&value, dsize);
235     matrix.setM43(value);
236     stream->read(&value, dsize);
237     matrix.setM44(value);
238 }
239
240 void serializeLayer(LayerAndroid* layer, SkWStream* stream)
241 {
242     if (!layer) {
243         XLOG("NULL layer!");
244         stream->write8(LTNone);
245         return;
246     }
247     if (layer->isMedia() || layer->isVideo()) {
248         XLOG("Layer isn't supported for serialization: isMedia: %s, isVideo: %s",
249              layer->isMedia() ? "true" : "false",
250              layer->isVideo() ? "true" : "false");
251         stream->write8(LTNone);
252         return;
253     }
254     LayerTypes type = layer->contentIsScrollable()
255             ? LTScrollableLayerAndroid
256             : LTLayerAndroid;
257     stream->write8(type);
258
259     // Start with Layer fields
260     stream->writeBool(layer->isInheritFromRootTransform());
261     stream->writeScalar(layer->getOpacity());
262     stream->writeScalar(layer->getSize().width());
263     stream->writeScalar(layer->getSize().height());
264     stream->writeScalar(layer->getPosition().x());
265     stream->writeScalar(layer->getPosition().y());
266     stream->writeScalar(layer->getAnchorPoint().x());
267     stream->writeScalar(layer->getAnchorPoint().y());
268     writeMatrix(stream, layer->getMatrix());
269     writeMatrix(stream, layer->getChildrenMatrix());
270
271     // Next up, LayerAndroid fields
272     stream->writeBool(layer->m_haveClip);
273     stream->writeBool(layer->m_isFixed);
274     stream->writeBool(layer->m_backgroundColorSet);
275     stream->writeBool(layer->m_isIframe);
276     writeSkLength(stream, layer->m_fixedLeft);
277     writeSkLength(stream, layer->m_fixedTop);
278     writeSkLength(stream, layer->m_fixedRight);
279     writeSkLength(stream, layer->m_fixedBottom);
280     writeSkLength(stream, layer->m_fixedMarginLeft);
281     writeSkLength(stream, layer->m_fixedMarginTop);
282     writeSkLength(stream, layer->m_fixedMarginRight);
283     writeSkLength(stream, layer->m_fixedMarginBottom);
284     writeSkRect(stream, layer->m_fixedRect);
285     stream->write32(layer->m_renderLayerPos.x());
286     stream->write32(layer->m_renderLayerPos.y());
287     stream->writeBool(layer->m_backfaceVisibility);
288     stream->writeBool(layer->m_visible);
289     stream->write32(layer->m_backgroundColor);
290     stream->writeBool(layer->m_preserves3D);
291     stream->writeScalar(layer->m_anchorPointZ);
292     stream->writeScalar(layer->m_drawOpacity);
293     bool hasContentsImage = layer->m_contentsImage != 0;
294     stream->writeBool(hasContentsImage);
295     if (hasContentsImage) {
296         SkFlattenableWriteBuffer buffer(1024);
297         buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
298         layer->m_contentsImage->flatten(buffer);
299         stream->write32(buffer.size());
300         buffer.writeToStream(stream);
301     }
302     bool hasRecordingPicture = layer->m_recordingPicture != 0;
303     stream->writeBool(hasRecordingPicture);
304     if (hasRecordingPicture)
305         layer->m_recordingPicture->serialize(stream);
306     // TODO: support m_animations (maybe?)
307     stream->write32(0); // placeholder for m_animations.size();
308     writeTransformationMatrix(stream, layer->m_transform);
309     writeTransformationMatrix(stream, layer->m_childrenTransform);
310     if (type == LTScrollableLayerAndroid) {
311         ScrollableLayerAndroid* scrollableLayer =
312                 static_cast<ScrollableLayerAndroid*>(layer);
313         stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft);
314         stream->writeScalar(scrollableLayer->m_scrollLimits.fTop);
315         stream->writeScalar(scrollableLayer->m_scrollLimits.width());
316         stream->writeScalar(scrollableLayer->m_scrollLimits.height());
317     }
318     int childCount = layer->countChildren();
319     stream->write32(childCount);
320     for (int i = 0; i < childCount; i++)
321         serializeLayer(layer->getChild(i), stream);
322 }
323
324 LayerAndroid* deserializeLayer(SkStream* stream)
325 {
326     int type = stream->readU8();
327     if (type == LTNone)
328         return 0;
329     // Cast is to disambiguate between ctors.
330     LayerAndroid *layer;
331     if (type == LTLayerAndroid)
332         layer = new LayerAndroid((RenderLayer*) 0);
333     else if (type == LTScrollableLayerAndroid)
334         layer = new ScrollableLayerAndroid((RenderLayer*) 0);
335     else {
336         XLOG("Unexpected layer type: %d, aborting!", type);
337         return 0;
338     }
339
340     // Layer fields
341     layer->setInheritFromRootTransform(stream->readBool());
342     layer->setOpacity(stream->readScalar());
343     layer->setSize(stream->readScalar(), stream->readScalar());
344     layer->setPosition(stream->readScalar(), stream->readScalar());
345     layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
346     layer->setMatrix(readMatrix(stream));
347     layer->setChildrenMatrix(readMatrix(stream));
348
349     // LayerAndroid fields
350     layer->m_haveClip = stream->readBool();
351     layer->m_isFixed = stream->readBool();
352     layer->m_backgroundColorSet = stream->readBool();
353     layer->m_isIframe = stream->readBool();
354     layer->m_fixedLeft = readSkLength(stream);
355     layer->m_fixedTop = readSkLength(stream);
356     layer->m_fixedRight = readSkLength(stream);
357     layer->m_fixedBottom = readSkLength(stream);
358     layer->m_fixedMarginLeft = readSkLength(stream);
359     layer->m_fixedMarginTop = readSkLength(stream);
360     layer->m_fixedMarginRight = readSkLength(stream);
361     layer->m_fixedMarginBottom = readSkLength(stream);
362     layer->m_fixedRect = readSkRect(stream);
363     layer->m_renderLayerPos.setX(stream->readS32());
364     layer->m_renderLayerPos.setY(stream->readS32());
365     layer->m_backfaceVisibility = stream->readBool();
366     layer->m_visible = stream->readBool();
367     layer->m_backgroundColor = stream->readU32();
368     layer->m_preserves3D = stream->readBool();
369     layer->m_anchorPointZ = stream->readScalar();
370     layer->m_drawOpacity = stream->readScalar();
371     bool hasContentsImage = stream->readBool();
372     if (hasContentsImage) {
373         int size = stream->readU32();
374         SkAutoMalloc storage(size);
375         stream->read(storage.get(), size);
376         SkFlattenableReadBuffer buffer(storage.get(), size);
377         layer->m_contentsImage = new SkBitmap();
378         layer->m_contentsImage->unflatten(buffer);
379     }
380     bool hasRecordingPicture = stream->readBool();
381     if (hasRecordingPicture) {
382         layer->m_recordingPicture = new SkPicture(stream);
383     }
384     int animationCount = stream->readU32(); // TODO: Support (maybe?)
385     readTransformationMatrix(stream, layer->m_transform);
386     readTransformationMatrix(stream, layer->m_childrenTransform);
387     if (type == LTScrollableLayerAndroid) {
388         ScrollableLayerAndroid* scrollableLayer =
389                 static_cast<ScrollableLayerAndroid*>(layer);
390         scrollableLayer->m_scrollLimits.set(
391                 stream->readScalar(),
392                 stream->readScalar(),
393                 stream->readScalar(),
394                 stream->readScalar());
395     }
396     int childCount = stream->readU32();
397     for (int i = 0; i < childCount; i++) {
398         LayerAndroid *childLayer = deserializeLayer(stream);
399         if (childLayer)
400             layer->addChild(childLayer);
401     }
402     layer->needsRepaint();
403     XLOG("Created layer with id %d", layer->uniqueId());
404     return layer;
405 }
406
407 /*
408  * JNI registration
409  */
410 static JNINativeMethod gSerializerMethods[] = {
411     { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
412         (void*) nativeSerializeViewState },
413     { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I",
414         (void*) nativeDeserializeViewState },
415 };
416
417 int registerViewStateSerializer(JNIEnv* env)
418 {
419     return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer",
420                                     gSerializerMethods, NELEM(gSerializerMethods));
421 }
422
423 }