• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ImagesManager.h"
31 #include "Layer.h"
32 #include "LayerAndroid.h"
33 #include "PictureSet.h"
34 #include "ScrollableLayerAndroid.h"
35 #include "SkPicture.h"
36 #include "TilesManager.h"
37 
38 #include <JNIUtility.h>
39 #include <JNIHelp.h>
40 #include <jni.h>
41 
42 #ifdef DEBUG
43 
44 #undef XLOG
45 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__)
46 
47 #else
48 
49 #undef XLOG
50 #define XLOG(...)
51 
52 #endif // DEBUG
53 
54 namespace android {
55 
56 enum LayerTypes {
57     LTNone = 0,
58     LTLayerAndroid = 1,
59     LTScrollableLayerAndroid = 2,
60 };
61 
nativeSerializeViewState(JNIEnv * env,jobject,jint jbaseLayer,jobject jstream,jbyteArray jstorage)62 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
63                                      jobject jstream, jbyteArray jstorage)
64 {
65     BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer;
66     if (!baseLayer)
67         return false;
68 
69     SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
70 #if USE(ACCELERATED_COMPOSITING)
71     stream->write32(baseLayer->getBackgroundColor().rgb());
72 #else
73     stream->write32(0);
74 #endif
75     SkPicture picture;
76     PictureSet* content = baseLayer->content();
77     baseLayer->drawCanvas(picture.beginRecording(content->width(), content->height(),
78             SkPicture::kUsePathBoundsForClip_RecordingFlag));
79     picture.endRecording();
80     if (!stream)
81         return false;
82     picture.serialize(stream);
83     int childCount = baseLayer->countChildren();
84     XLOG("BaseLayer has %d child(ren)", childCount);
85     stream->write32(childCount);
86     for (int i = 0; i < childCount; i++) {
87         LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i));
88         serializeLayer(layer, stream);
89     }
90     delete stream;
91     return true;
92 }
93 
nativeDeserializeViewState(JNIEnv * env,jobject,jobject jstream,jbyteArray jstorage)94 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobject jstream,
95                                       jbyteArray jstorage)
96 {
97     SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
98     if (!stream)
99         return 0;
100     BaseLayerAndroid* layer = new BaseLayerAndroid();
101     Color color = stream->readU32();
102 #if USE(ACCELERATED_COMPOSITING)
103     layer->setBackgroundColor(color);
104 #endif
105     SkPicture* picture = new SkPicture(stream);
106     layer->setContent(picture);
107     SkSafeUnref(picture);
108     int childCount = stream->readS32();
109     for (int i = 0; i < childCount; i++) {
110         LayerAndroid* childLayer = deserializeLayer(stream);
111         if (childLayer)
112             layer->addChild(childLayer);
113     }
114     // Now double back and delete any imageRefs
115     for (int i = 0; i < layer->countChildren(); i++) {
116         LayerAndroid* childLayer = static_cast<LayerAndroid*>(layer->getChild(i));
117         cleanupImageRefs(childLayer);
118     }
119     delete stream;
120     return layer;
121 }
122 
123 // Serialization helpers
124 
writeMatrix(SkWStream * stream,const SkMatrix & matrix)125 void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
126 {
127     for (int i = 0; i < 9; i++)
128         stream->writeScalar(matrix[i]);
129 }
130 
readMatrix(SkStream * stream)131 SkMatrix readMatrix(SkStream *stream)
132 {
133     SkMatrix matrix;
134     for (int i = 0; i < 9; i++)
135         matrix.set(i, stream->readScalar());
136     return matrix;
137 }
138 
writeSkLength(SkWStream * stream,SkLength length)139 void writeSkLength(SkWStream *stream, SkLength length)
140 {
141     stream->write32(length.type);
142     stream->writeScalar(length.value);
143 }
144 
readSkLength(SkStream * stream)145 SkLength readSkLength(SkStream *stream)
146 {
147     SkLength len;
148     len.type = (SkLength::SkLengthType) stream->readU32();
149     len.value = stream->readScalar();
150     return len;
151 }
152 
writeSkRect(SkWStream * stream,SkRect rect)153 void writeSkRect(SkWStream *stream, SkRect rect)
154 {
155     stream->writeScalar(rect.fLeft);
156     stream->writeScalar(rect.fTop);
157     stream->writeScalar(rect.fRight);
158     stream->writeScalar(rect.fBottom);
159 }
160 
readSkRect(SkStream * stream)161 SkRect readSkRect(SkStream *stream)
162 {
163     SkRect rect;
164     rect.fLeft = stream->readScalar();
165     rect.fTop = stream->readScalar();
166     rect.fRight = stream->readScalar();
167     rect.fBottom = stream->readScalar();
168     return rect;
169 }
170 
writeTransformationMatrix(SkWStream * stream,TransformationMatrix & matrix)171 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
172 {
173     double value;
174     int dsize = sizeof(double);
175     value = matrix.m11();
176     stream->write(&value, dsize);
177     value = matrix.m12();
178     stream->write(&value, dsize);
179     value = matrix.m13();
180     stream->write(&value, dsize);
181     value = matrix.m14();
182     stream->write(&value, dsize);
183     value = matrix.m21();
184     stream->write(&value, dsize);
185     value = matrix.m22();
186     stream->write(&value, dsize);
187     value = matrix.m23();
188     stream->write(&value, dsize);
189     value = matrix.m24();
190     stream->write(&value, dsize);
191     value = matrix.m31();
192     stream->write(&value, dsize);
193     value = matrix.m32();
194     stream->write(&value, dsize);
195     value = matrix.m33();
196     stream->write(&value, dsize);
197     value = matrix.m34();
198     stream->write(&value, dsize);
199     value = matrix.m41();
200     stream->write(&value, dsize);
201     value = matrix.m42();
202     stream->write(&value, dsize);
203     value = matrix.m43();
204     stream->write(&value, dsize);
205     value = matrix.m44();
206     stream->write(&value, dsize);
207 }
208 
readTransformationMatrix(SkStream * stream,TransformationMatrix & matrix)209 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
210 {
211     double value;
212     int dsize = sizeof(double);
213     stream->read(&value, dsize);
214     matrix.setM11(value);
215     stream->read(&value, dsize);
216     matrix.setM12(value);
217     stream->read(&value, dsize);
218     matrix.setM13(value);
219     stream->read(&value, dsize);
220     matrix.setM14(value);
221     stream->read(&value, dsize);
222     matrix.setM21(value);
223     stream->read(&value, dsize);
224     matrix.setM22(value);
225     stream->read(&value, dsize);
226     matrix.setM23(value);
227     stream->read(&value, dsize);
228     matrix.setM24(value);
229     stream->read(&value, dsize);
230     matrix.setM31(value);
231     stream->read(&value, dsize);
232     matrix.setM32(value);
233     stream->read(&value, dsize);
234     matrix.setM33(value);
235     stream->read(&value, dsize);
236     matrix.setM34(value);
237     stream->read(&value, dsize);
238     matrix.setM41(value);
239     stream->read(&value, dsize);
240     matrix.setM42(value);
241     stream->read(&value, dsize);
242     matrix.setM43(value);
243     stream->read(&value, dsize);
244     matrix.setM44(value);
245 }
246 
serializeLayer(LayerAndroid * layer,SkWStream * stream)247 void serializeLayer(LayerAndroid* layer, SkWStream* stream)
248 {
249     if (!layer) {
250         XLOG("NULL layer!");
251         stream->write8(LTNone);
252         return;
253     }
254     if (layer->isMedia() || layer->isVideo()) {
255         XLOG("Layer isn't supported for serialization: isMedia: %s, isVideo: %s",
256              layer->isMedia() ? "true" : "false",
257              layer->isVideo() ? "true" : "false");
258         stream->write8(LTNone);
259         return;
260     }
261     LayerTypes type = layer->contentIsScrollable()
262             ? LTScrollableLayerAndroid
263             : LTLayerAndroid;
264     stream->write8(type);
265 
266     // Start with Layer fields
267     stream->writeBool(layer->shouldInheritFromRootTransform());
268     stream->writeScalar(layer->getOpacity());
269     stream->writeScalar(layer->getSize().width());
270     stream->writeScalar(layer->getSize().height());
271     stream->writeScalar(layer->getPosition().x());
272     stream->writeScalar(layer->getPosition().y());
273     stream->writeScalar(layer->getAnchorPoint().x());
274     stream->writeScalar(layer->getAnchorPoint().y());
275     writeMatrix(stream, layer->getMatrix());
276     writeMatrix(stream, layer->getChildrenMatrix());
277 
278     // Next up, LayerAndroid fields
279     stream->writeBool(layer->m_haveClip);
280     stream->writeBool(layer->m_isFixed);
281     stream->writeBool(layer->m_backgroundColorSet);
282     stream->writeBool(layer->m_isIframe);
283     writeSkLength(stream, layer->m_fixedLeft);
284     writeSkLength(stream, layer->m_fixedTop);
285     writeSkLength(stream, layer->m_fixedRight);
286     writeSkLength(stream, layer->m_fixedBottom);
287     writeSkLength(stream, layer->m_fixedMarginLeft);
288     writeSkLength(stream, layer->m_fixedMarginTop);
289     writeSkLength(stream, layer->m_fixedMarginRight);
290     writeSkLength(stream, layer->m_fixedMarginBottom);
291     writeSkRect(stream, layer->m_fixedRect);
292     stream->write32(layer->m_renderLayerPos.x());
293     stream->write32(layer->m_renderLayerPos.y());
294     stream->writeBool(layer->m_backfaceVisibility);
295     stream->writeBool(layer->m_visible);
296     stream->write32(layer->m_backgroundColor);
297     stream->writeBool(layer->m_preserves3D);
298     stream->writeScalar(layer->m_anchorPointZ);
299     stream->writeScalar(layer->m_drawOpacity);
300     bool hasContentsImage = layer->m_imageRef != 0;
301     stream->writeBool(hasContentsImage);
302     if (hasContentsImage) {
303         SkFlattenableWriteBuffer buffer(1024);
304         buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
305         ImageTexture* imagetexture =
306                 ImagesManager::instance()->getTextureForImage(layer->m_imageRef, false);
307         if (imagetexture && imagetexture->bitmap())
308             imagetexture->bitmap()->flatten(buffer);
309         stream->write32(buffer.size());
310         buffer.writeToStream(stream);
311     }
312     bool hasRecordingPicture = layer->m_recordingPicture != 0;
313     stream->writeBool(hasRecordingPicture);
314     if (hasRecordingPicture)
315         layer->m_recordingPicture->serialize(stream);
316     // TODO: support m_animations (maybe?)
317     stream->write32(0); // placeholder for m_animations.size();
318     writeTransformationMatrix(stream, layer->m_transform);
319     writeTransformationMatrix(stream, layer->m_childrenTransform);
320     if (type == LTScrollableLayerAndroid) {
321         ScrollableLayerAndroid* scrollableLayer =
322                 static_cast<ScrollableLayerAndroid*>(layer);
323         stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft);
324         stream->writeScalar(scrollableLayer->m_scrollLimits.fTop);
325         stream->writeScalar(scrollableLayer->m_scrollLimits.width());
326         stream->writeScalar(scrollableLayer->m_scrollLimits.height());
327     }
328     int childCount = layer->countChildren();
329     stream->write32(childCount);
330     for (int i = 0; i < childCount; i++)
331         serializeLayer(layer->getChild(i), stream);
332 }
333 
deserializeLayer(SkStream * stream)334 LayerAndroid* deserializeLayer(SkStream* stream)
335 {
336     int type = stream->readU8();
337     if (type == LTNone)
338         return 0;
339     // Cast is to disambiguate between ctors.
340     LayerAndroid *layer;
341     if (type == LTLayerAndroid)
342         layer = new LayerAndroid((RenderLayer*) 0);
343     else if (type == LTScrollableLayerAndroid)
344         layer = new ScrollableLayerAndroid((RenderLayer*) 0);
345     else {
346         XLOG("Unexpected layer type: %d, aborting!", type);
347         return 0;
348     }
349 
350     // Layer fields
351     layer->setShouldInheritFromRootTransform(stream->readBool());
352     layer->setOpacity(stream->readScalar());
353     layer->setSize(stream->readScalar(), stream->readScalar());
354     layer->setPosition(stream->readScalar(), stream->readScalar());
355     layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
356     layer->setMatrix(readMatrix(stream));
357     layer->setChildrenMatrix(readMatrix(stream));
358 
359     // LayerAndroid fields
360     layer->m_haveClip = stream->readBool();
361     layer->m_isFixed = stream->readBool();
362     layer->m_backgroundColorSet = stream->readBool();
363     layer->m_isIframe = stream->readBool();
364     layer->m_fixedLeft = readSkLength(stream);
365     layer->m_fixedTop = readSkLength(stream);
366     layer->m_fixedRight = readSkLength(stream);
367     layer->m_fixedBottom = readSkLength(stream);
368     layer->m_fixedMarginLeft = readSkLength(stream);
369     layer->m_fixedMarginTop = readSkLength(stream);
370     layer->m_fixedMarginRight = readSkLength(stream);
371     layer->m_fixedMarginBottom = readSkLength(stream);
372     layer->m_fixedRect = readSkRect(stream);
373     layer->m_renderLayerPos.setX(stream->readS32());
374     layer->m_renderLayerPos.setY(stream->readS32());
375     layer->m_backfaceVisibility = stream->readBool();
376     layer->m_visible = stream->readBool();
377     layer->m_backgroundColor = stream->readU32();
378     layer->m_preserves3D = stream->readBool();
379     layer->m_anchorPointZ = stream->readScalar();
380     layer->m_drawOpacity = stream->readScalar();
381     bool hasContentsImage = stream->readBool();
382     if (hasContentsImage) {
383         int size = stream->readU32();
384         SkAutoMalloc storage(size);
385         stream->read(storage.get(), size);
386         SkFlattenableReadBuffer buffer(storage.get(), size);
387         SkBitmap contentsImage;
388         contentsImage.unflatten(buffer);
389         SkBitmapRef* imageRef = new SkBitmapRef(contentsImage);
390         layer->setContentsImage(imageRef);
391         // We delay deleting the imageRef until after deserialization to make
392         // sure we have unique keys
393     }
394     bool hasRecordingPicture = stream->readBool();
395     if (hasRecordingPicture) {
396         layer->m_recordingPicture = new SkPicture(stream);
397     }
398     int animationCount = stream->readU32(); // TODO: Support (maybe?)
399     readTransformationMatrix(stream, layer->m_transform);
400     readTransformationMatrix(stream, layer->m_childrenTransform);
401     if (type == LTScrollableLayerAndroid) {
402         ScrollableLayerAndroid* scrollableLayer =
403                 static_cast<ScrollableLayerAndroid*>(layer);
404         scrollableLayer->m_scrollLimits.set(
405                 stream->readScalar(),
406                 stream->readScalar(),
407                 stream->readScalar(),
408                 stream->readScalar());
409     }
410     int childCount = stream->readU32();
411     for (int i = 0; i < childCount; i++) {
412         LayerAndroid *childLayer = deserializeLayer(stream);
413         if (childLayer)
414             layer->addChild(childLayer);
415     }
416     layer->needsRepaint();
417     XLOG("Created layer with id %d", layer->uniqueId());
418     return layer;
419 }
420 
cleanupImageRefs(LayerAndroid * layer)421 void cleanupImageRefs(LayerAndroid* layer)
422 {
423     if (!layer)
424         return;
425     int count = layer->countChildren();
426     for (int i = 0; i < count; i++)
427         cleanupImageRefs(layer->getChild(i));
428     if (layer->m_imageRef)
429         delete layer->m_imageRef;
430 }
431 
432 /*
433  * JNI registration
434  */
435 static JNINativeMethod gSerializerMethods[] = {
436     { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
437         (void*) nativeSerializeViewState },
438     { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I",
439         (void*) nativeDeserializeViewState },
440 };
441 
registerViewStateSerializer(JNIEnv * env)442 int registerViewStateSerializer(JNIEnv* env)
443 {
444     return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer",
445                                     gSerializerMethods, NELEM(gSerializerMethods));
446 }
447 
448 }
449