OSDN Git Service

Fix image layer codepath
[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 "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
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
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     delete stream;
115     return layer;
116 }
117
118 // Serialization helpers
119
120 void writeMatrix(SkWStream *stream, const SkMatrix& matrix)
121 {
122     for (int i = 0; i < 9; i++)
123         stream->writeScalar(matrix[i]);
124 }
125
126 SkMatrix readMatrix(SkStream *stream)
127 {
128     SkMatrix matrix;
129     for (int i = 0; i < 9; i++)
130         matrix.set(i, stream->readScalar());
131     return matrix;
132 }
133
134 void writeSkLength(SkWStream *stream, SkLength length)
135 {
136     stream->write32(length.type);
137     stream->writeScalar(length.value);
138 }
139
140 SkLength readSkLength(SkStream *stream)
141 {
142     SkLength len;
143     len.type = (SkLength::SkLengthType) stream->readU32();
144     len.value = stream->readScalar();
145     return len;
146 }
147
148 void writeSkRect(SkWStream *stream, SkRect rect)
149 {
150     stream->writeScalar(rect.fLeft);
151     stream->writeScalar(rect.fTop);
152     stream->writeScalar(rect.fRight);
153     stream->writeScalar(rect.fBottom);
154 }
155
156 SkRect readSkRect(SkStream *stream)
157 {
158     SkRect rect;
159     rect.fLeft = stream->readScalar();
160     rect.fTop = stream->readScalar();
161     rect.fRight = stream->readScalar();
162     rect.fBottom = stream->readScalar();
163     return rect;
164 }
165
166 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix)
167 {
168     double value;
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);
202 }
203
204 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix)
205 {
206     double value;
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);
240 }
241
242 void serializeLayer(LayerAndroid* layer, SkWStream* stream)
243 {
244     if (!layer) {
245         XLOG("NULL layer!");
246         stream->write8(LTNone);
247         return;
248     }
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);
254         return;
255     }
256     LayerTypes type = layer->contentIsScrollable()
257             ? LTScrollableLayerAndroid
258             : LTLayerAndroid;
259     stream->write8(type);
260
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());
272
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);
307     }
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());
323     }
324     int childCount = layer->countChildren();
325     stream->write32(childCount);
326     for (int i = 0; i < childCount; i++)
327         serializeLayer(layer->getChild(i), stream);
328 }
329
330 LayerAndroid* deserializeLayer(SkStream* stream)
331 {
332     int type = stream->readU8();
333     if (type == LTNone)
334         return 0;
335     // Cast is to disambiguate between ctors.
336     LayerAndroid *layer;
337     if (type == LTLayerAndroid)
338         layer = new LayerAndroid((RenderLayer*) 0);
339     else if (type == LTScrollableLayerAndroid)
340         layer = new ScrollableLayerAndroid((RenderLayer*) 0);
341     else {
342         XLOG("Unexpected layer type: %d, aborting!", type);
343         return 0;
344     }
345
346     // Layer fields
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));
354
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);
387         delete imageRef;
388     }
389     bool hasRecordingPicture = stream->readBool();
390     if (hasRecordingPicture) {
391         layer->m_recordingPicture = new SkPicture(stream);
392     }
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());
404     }
405     int childCount = stream->readU32();
406     for (int i = 0; i < childCount; i++) {
407         LayerAndroid *childLayer = deserializeLayer(stream);
408         if (childLayer)
409             layer->addChild(childLayer);
410     }
411     layer->needsRepaint();
412     XLOG("Created layer with id %d", layer->uniqueId());
413     return layer;
414 }
415
416 /*
417  * JNI registration
418  */
419 static JNINativeMethod gSerializerMethods[] = {
420     { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z",
421         (void*) nativeSerializeViewState },
422     { "nativeDeserializeViewState", "(Ljava/io/InputStream;[B)I",
423         (void*) nativeDeserializeViewState },
424 };
425
426 int registerViewStateSerializer(JNIEnv* env)
427 {
428     return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer",
429                                     gSerializerMethods, NELEM(gSerializerMethods));
430 }
431
432 }