2 * Copyright 2011, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #include "BaseLayerAndroid.h"
29 #include "CreateJavaOutputStreamAdaptor.h"
30 #include "ImagesManager.h"
32 #include "LayerAndroid.h"
33 #include "PictureSet.h"
34 #include "ScrollableLayerAndroid.h"
35 #include "SkPicture.h"
36 #include "TilesManager.h"
38 #include <JNIUtility.h>
45 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "ViewStateSerializer", __VA_ARGS__)
59 LTScrollableLayerAndroid = 2,
62 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer,
63 jobject jstream, jbyteArray jstorage)
65 BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer;
69 SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage);
70 #if USE(ACCELERATED_COMPOSITING)
71 stream->write32(baseLayer->getBackgroundColor().rgb());
76 PictureSet* content = baseLayer->content();
77 baseLayer->drawCanvas(picture.beginRecording(content->width(), content->height(),
78 SkPicture::kUsePathBoundsForClip_RecordingFlag));
79 picture.endRecording();
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);
94 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jobject jstream,
97 SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
100 BaseLayerAndroid* layer = new BaseLayerAndroid();
101 Color color = stream->readU32();
102 #if USE(ACCELERATED_COMPOSITING)
103 layer->setBackgroundColor(color);
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);
112 layer->addChild(childLayer);
118 // Serialization helpers
120 void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
122 for (int i = 0; i < 9; i++)
123 stream->writeScalar(matrix[i]);
126 SkMatrix readMatrix(SkStream *stream)
129 for (int i = 0; i < 9; i++)
130 matrix.set(i, stream->readScalar());
134 void writeSkLength(SkWStream *stream, SkLength length)
136 stream->write32(length.type);
137 stream->writeScalar(length.value);
140 SkLength readSkLength(SkStream *stream)
143 len.type = (SkLength::SkLengthType) stream->readU32();
144 len.value = stream->readScalar();
148 void writeSkRect(SkWStream *stream, SkRect rect)
150 stream->writeScalar(rect.fLeft);
151 stream->writeScalar(rect.fTop);
152 stream->writeScalar(rect.fRight);
153 stream->writeScalar(rect.fBottom);
156 SkRect readSkRect(SkStream *stream)
159 rect.fLeft = stream->readScalar();
160 rect.fTop = stream->readScalar();
161 rect.fRight = stream->readScalar();
162 rect.fBottom = stream->readScalar();
166 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
169 int dsize = sizeof(double);
170 value = matrix.m11();
171 stream->write(&value, dsize);
172 value = matrix.m12();
173 stream->write(&value, dsize);
174 value = matrix.m13();
175 stream->write(&value, dsize);
176 value = matrix.m14();
177 stream->write(&value, dsize);
178 value = matrix.m21();
179 stream->write(&value, dsize);
180 value = matrix.m22();
181 stream->write(&value, dsize);
182 value = matrix.m23();
183 stream->write(&value, dsize);
184 value = matrix.m24();
185 stream->write(&value, dsize);
186 value = matrix.m31();
187 stream->write(&value, dsize);
188 value = matrix.m32();
189 stream->write(&value, dsize);
190 value = matrix.m33();
191 stream->write(&value, dsize);
192 value = matrix.m34();
193 stream->write(&value, dsize);
194 value = matrix.m41();
195 stream->write(&value, dsize);
196 value = matrix.m42();
197 stream->write(&value, dsize);
198 value = matrix.m43();
199 stream->write(&value, dsize);
200 value = matrix.m44();
201 stream->write(&value, dsize);
204 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
207 int dsize = sizeof(double);
208 stream->read(&value, dsize);
209 matrix.setM11(value);
210 stream->read(&value, dsize);
211 matrix.setM12(value);
212 stream->read(&value, dsize);
213 matrix.setM13(value);
214 stream->read(&value, dsize);
215 matrix.setM14(value);
216 stream->read(&value, dsize);
217 matrix.setM21(value);
218 stream->read(&value, dsize);
219 matrix.setM22(value);
220 stream->read(&value, dsize);
221 matrix.setM23(value);
222 stream->read(&value, dsize);
223 matrix.setM24(value);
224 stream->read(&value, dsize);
225 matrix.setM31(value);
226 stream->read(&value, dsize);
227 matrix.setM32(value);
228 stream->read(&value, dsize);
229 matrix.setM33(value);
230 stream->read(&value, dsize);
231 matrix.setM34(value);
232 stream->read(&value, dsize);
233 matrix.setM41(value);
234 stream->read(&value, dsize);
235 matrix.setM42(value);
236 stream->read(&value, dsize);
237 matrix.setM43(value);
238 stream->read(&value, dsize);
239 matrix.setM44(value);
242 void serializeLayer(LayerAndroid* layer, SkWStream* stream)
246 stream->write8(LTNone);
249 if (layer->isMedia() || layer->isVideo()) {
250 XLOG("Layer isn't supported for serialization: isMedia: %s, isVideo: %s",
251 layer->isMedia() ? "true" : "false",
252 layer->isVideo() ? "true" : "false");
253 stream->write8(LTNone);
256 LayerTypes type = layer->contentIsScrollable()
257 ? LTScrollableLayerAndroid
259 stream->write8(type);
261 // Start with Layer fields
262 stream->writeBool(layer->shouldInheritFromRootTransform());
263 stream->writeScalar(layer->getOpacity());
264 stream->writeScalar(layer->getSize().width());
265 stream->writeScalar(layer->getSize().height());
266 stream->writeScalar(layer->getPosition().x());
267 stream->writeScalar(layer->getPosition().y());
268 stream->writeScalar(layer->getAnchorPoint().x());
269 stream->writeScalar(layer->getAnchorPoint().y());
270 writeMatrix(stream, layer->getMatrix());
271 writeMatrix(stream, layer->getChildrenMatrix());
273 // Next up, LayerAndroid fields
274 stream->writeBool(layer->m_haveClip);
275 stream->writeBool(layer->m_isFixed);
276 stream->writeBool(layer->m_backgroundColorSet);
277 stream->writeBool(layer->m_isIframe);
278 writeSkLength(stream, layer->m_fixedLeft);
279 writeSkLength(stream, layer->m_fixedTop);
280 writeSkLength(stream, layer->m_fixedRight);
281 writeSkLength(stream, layer->m_fixedBottom);
282 writeSkLength(stream, layer->m_fixedMarginLeft);
283 writeSkLength(stream, layer->m_fixedMarginTop);
284 writeSkLength(stream, layer->m_fixedMarginRight);
285 writeSkLength(stream, layer->m_fixedMarginBottom);
286 writeSkRect(stream, layer->m_fixedRect);
287 stream->write32(layer->m_renderLayerPos.x());
288 stream->write32(layer->m_renderLayerPos.y());
289 stream->writeBool(layer->m_backfaceVisibility);
290 stream->writeBool(layer->m_visible);
291 stream->write32(layer->m_backgroundColor);
292 stream->writeBool(layer->m_preserves3D);
293 stream->writeScalar(layer->m_anchorPointZ);
294 stream->writeScalar(layer->m_drawOpacity);
295 bool hasContentsImage = layer->m_imageCRC != 0;
296 stream->writeBool(hasContentsImage);
297 if (hasContentsImage) {
298 SkFlattenableWriteBuffer buffer(1024);
299 buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
300 ImageTexture* imagetexture =
301 ImagesManager::instance()->retainImage(layer->m_imageCRC);
302 if (imagetexture && imagetexture->bitmap())
303 imagetexture->bitmap()->flatten(buffer);
304 ImagesManager::instance()->releaseImage(layer->m_imageCRC);
305 stream->write32(buffer.size());
306 buffer.writeToStream(stream);
308 bool hasRecordingPicture = layer->m_recordingPicture != 0;
309 stream->writeBool(hasRecordingPicture);
310 if (hasRecordingPicture)
311 layer->m_recordingPicture->serialize(stream);
312 // TODO: support m_animations (maybe?)
313 stream->write32(0); // placeholder for m_animations.size();
314 writeTransformationMatrix(stream, layer->m_transform);
315 writeTransformationMatrix(stream, layer->m_childrenTransform);
316 if (type == LTScrollableLayerAndroid) {
317 ScrollableLayerAndroid* scrollableLayer =
318 static_cast<ScrollableLayerAndroid*>(layer);
319 stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft);
320 stream->writeScalar(scrollableLayer->m_scrollLimits.fTop);
321 stream->writeScalar(scrollableLayer->m_scrollLimits.width());
322 stream->writeScalar(scrollableLayer->m_scrollLimits.height());
324 int childCount = layer->countChildren();
325 stream->write32(childCount);
326 for (int i = 0; i < childCount; i++)
327 serializeLayer(layer->getChild(i), stream);
330 LayerAndroid* deserializeLayer(SkStream* stream)
332 int type = stream->readU8();
335 // Cast is to disambiguate between ctors.
337 if (type == LTLayerAndroid)
338 layer = new LayerAndroid((RenderLayer*) 0);
339 else if (type == LTScrollableLayerAndroid)
340 layer = new ScrollableLayerAndroid((RenderLayer*) 0);
342 XLOG("Unexpected layer type: %d, aborting!", type);
347 layer->setShouldInheritFromRootTransform(stream->readBool());
348 layer->setOpacity(stream->readScalar());
349 layer->setSize(stream->readScalar(), stream->readScalar());
350 layer->setPosition(stream->readScalar(), stream->readScalar());
351 layer->setAnchorPoint(stream->readScalar(), stream->readScalar());
352 layer->setMatrix(readMatrix(stream));
353 layer->setChildrenMatrix(readMatrix(stream));
355 // LayerAndroid fields
356 layer->m_haveClip = stream->readBool();
357 layer->m_isFixed = stream->readBool();
358 layer->m_backgroundColorSet = stream->readBool();
359 layer->m_isIframe = stream->readBool();
360 layer->m_fixedLeft = readSkLength(stream);
361 layer->m_fixedTop = readSkLength(stream);
362 layer->m_fixedRight = readSkLength(stream);
363 layer->m_fixedBottom = readSkLength(stream);
364 layer->m_fixedMarginLeft = readSkLength(stream);
365 layer->m_fixedMarginTop = readSkLength(stream);
366 layer->m_fixedMarginRight = readSkLength(stream);
367 layer->m_fixedMarginBottom = readSkLength(stream);
368 layer->m_fixedRect = readSkRect(stream);
369 layer->m_renderLayerPos.setX(stream->readS32());
370 layer->m_renderLayerPos.setY(stream->readS32());
371 layer->m_backfaceVisibility = stream->readBool();
372 layer->m_visible = stream->readBool();
373 layer->m_backgroundColor = stream->readU32();
374 layer->m_preserves3D = stream->readBool();
375 layer->m_anchorPointZ = stream->readScalar();
376 layer->m_drawOpacity = stream->readScalar();
377 bool hasContentsImage = stream->readBool();
378 if (hasContentsImage) {
379 int size = stream->readU32();
380 SkAutoMalloc storage(size);
381 stream->read(storage.get(), size);
382 SkFlattenableReadBuffer buffer(storage.get(), size);
383 SkBitmap contentsImage;
384 contentsImage.unflatten(buffer);
385 SkBitmapRef* imageRef = new SkBitmapRef(contentsImage);
386 layer->setContentsImage(imageRef);
389 bool hasRecordingPicture = stream->readBool();
390 if (hasRecordingPicture) {
391 layer->m_recordingPicture = new SkPicture(stream);
393 int animationCount = stream->readU32(); // TODO: Support (maybe?)
394 readTransformationMatrix(stream, layer->m_transform);
395 readTransformationMatrix(stream, layer->m_childrenTransform);
396 if (type == LTScrollableLayerAndroid) {
397 ScrollableLayerAndroid* scrollableLayer =
398 static_cast<ScrollableLayerAndroid*>(layer);
399 scrollableLayer->m_scrollLimits.set(
400 stream->readScalar(),
401 stream->readScalar(),
402 stream->readScalar(),
403 stream->readScalar());
405 int childCount = stream->readU32();
406 for (int i = 0; i < childCount; i++) {
407 LayerAndroid *childLayer = deserializeLayer(stream);
409 layer->addChild(childLayer);
411 layer->needsRepaint();
412 XLOG("Created layer with id %d", layer->uniqueId());
419 static JNINativeMethod gSerializerMethods[] = {
420 { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
421 (void*) nativeSerializeViewState },
422 { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I",
423 (void*) nativeDeserializeViewState },
426 int registerViewStateSerializer(JNIEnv* env)
428 return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer",
429 gSerializerMethods, NELEM(gSerializerMethods));