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 } 433