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