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 #define LOG_TAG "ViewStateSerializer" 27 #define LOG_NDEBUG 1 28 29 #include "config.h" 30 31 #include "BaseLayerAndroid.h" 32 #include "CreateJavaOutputStreamAdaptor.h" 33 #include "DumpLayer.h" 34 #include "FixedPositioning.h" 35 #include "ImagesManager.h" 36 #include "IFrameContentLayerAndroid.h" 37 #include "IFrameLayerAndroid.h" 38 #include "Layer.h" 39 #include "LayerAndroid.h" 40 #include "LayerContent.h" 41 #include "PictureLayerContent.h" 42 #include "ScrollableLayerAndroid.h" 43 #include "SkData.h" 44 #include "SkOrderedReadBuffer.h" 45 #include "SkOrderedWriteBuffer.h" 46 #include "SkPicture.h" 47 #include "TilesManager.h" 48 49 #include <JNIUtility.h> 50 #include <JNIHelp.h> 51 #include <jni.h> 52 53 namespace android { 54 55 enum LayerTypes { 56 LTNone = 0, 57 LTLayerAndroid = 1, 58 LTScrollableLayerAndroid = 2, 59 LTFixedLayerAndroid = 3 60 }; 61 62 #define ID "mID" 63 #define LEFT "layout:mLeft" 64 #define TOP "layout:mTop" 65 #define WIDTH "layout:getWidth()" 66 #define HEIGHT "layout:getHeight()" 67 68 class HierarchyLayerDumper : public LayerDumper { 69 public: 70 HierarchyLayerDumper(SkWStream* stream, int level) 71 : LayerDumper(level) 72 , m_stream(stream) 73 {} 74 75 virtual void beginLayer(const char* className, const LayerAndroid* layerPtr) { 76 LayerDumper::beginLayer(className, layerPtr); 77 for (int i = 0; i < m_indentLevel; i++) { 78 m_stream->writeText(" "); 79 } 80 m_stream->writeText(className); 81 m_stream->writeText("@"); 82 m_stream->writeHexAsText(layerPtr->uniqueId()); 83 m_stream->writeText(" "); 84 85 writeHexVal(ID, (int) layerPtr); 86 writeIntVal(LEFT, layerPtr->getPosition().fX); 87 writeIntVal(TOP, layerPtr->getPosition().fY); 88 writeIntVal(WIDTH, layerPtr->getWidth()); 89 writeIntVal(HEIGHT, layerPtr->getHeight()); 90 } 91 92 virtual void beginChildren(int childCount) { 93 m_stream->writeText("\n"); 94 LayerDumper::beginChildren(childCount); 95 } 96 97 protected: 98 virtual void writeEntry(const char* label, const char* value) { 99 m_stream->writeText(label); 100 m_stream->writeText("="); 101 int len = strlen(value); 102 m_stream->writeDecAsText(len); 103 m_stream->writeText(","); 104 m_stream->writeText(value); 105 m_stream->writeText(" "); 106 } 107 108 private: 109 SkWStream* m_stream; 110 }; 111 112 static void nativeDumpLayerHierarchy(JNIEnv* env, jobject, jint jbaseLayer, jint level, 113 jobject jstream, jbyteArray jstorage) 114 { 115 SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 116 BaseLayerAndroid* baseLayer = reinterpret_cast<BaseLayerAndroid*>(jbaseLayer); 117 SkSafeRef(baseLayer); 118 HierarchyLayerDumper dumper(stream, level); 119 baseLayer->dumpLayers(&dumper); 120 SkSafeUnref(baseLayer); 121 delete stream; 122 } 123 124 static bool nativeSerializeViewState(JNIEnv* env, jobject, jint jbaseLayer, 125 jobject jstream, jbyteArray jstorage) 126 { 127 BaseLayerAndroid* baseLayer = (BaseLayerAndroid*) jbaseLayer; 128 if (!baseLayer) 129 return false; 130 131 SkWStream *stream = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 132 #if USE(ACCELERATED_COMPOSITING) 133 stream->write32(baseLayer->getBackgroundColor().rgb()); 134 #else 135 stream->write32(0); 136 #endif 137 if (!stream) 138 return false; 139 if (baseLayer->content()) 140 baseLayer->content()->serialize(stream); 141 else 142 return false; 143 int childCount = baseLayer->countChildren(); 144 ALOGV("BaseLayer has %d child(ren)", childCount); 145 stream->write32(childCount); 146 for (int i = 0; i < childCount; i++) { 147 LayerAndroid* layer = static_cast<LayerAndroid*>(baseLayer->getChild(i)); 148 serializeLayer(layer, stream); 149 } 150 delete stream; 151 return true; 152 } 153 154 static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version, 155 jobject jstream, jbyteArray jstorage) 156 { 157 SkStream* javaStream = CreateJavaInputStreamAdaptor(env, jstream, jstorage); 158 if (!javaStream) 159 return 0; 160 161 // read everything into memory so that we can get the offset into the stream 162 // when necessary. This is needed for the LegacyPictureLayerContent. 163 SkDynamicMemoryWStream tempStream; 164 const int bufferSize = 256*1024; // 256KB 165 uint8_t buffer[bufferSize]; 166 int bytesRead = 0; 167 168 do { 169 bytesRead = javaStream->read(buffer, bufferSize); 170 tempStream.write(buffer, bytesRead); 171 } while (bytesRead != 0); 172 173 SkMemoryStream stream; 174 stream.setData(tempStream.copyToData())->unref(); 175 176 // clean up the javaStream now that we have everything in memory 177 delete javaStream; 178 179 Color color = stream.readU32(); 180 181 182 183 LayerContent* content; 184 if (version == 1) { 185 content = new LegacyPictureLayerContent(&stream); 186 } else { 187 SkPicture* picture = new SkPicture(&stream); 188 content = new PictureLayerContent(picture); 189 SkSafeUnref(picture); 190 } 191 192 BaseLayerAndroid* layer = new BaseLayerAndroid(content); 193 layer->setBackgroundColor(color); 194 195 SkRegion dirtyRegion; 196 dirtyRegion.setRect(0, 0, content->width(), content->height()); 197 layer->markAsDirty(dirtyRegion); 198 199 SkSafeUnref(content); 200 int childCount = stream.readS32(); 201 for (int i = 0; i < childCount; i++) { 202 LayerAndroid* childLayer = deserializeLayer(version, &stream); 203 if (childLayer) 204 layer->addChild(childLayer); 205 } 206 return layer; 207 } 208 209 // Serialization helpers 210 211 void writeMatrix(SkWStream *stream, const SkMatrix& matrix) 212 { 213 for (int i = 0; i < 9; i++) 214 stream->writeScalar(matrix[i]); 215 } 216 217 SkMatrix readMatrix(SkStream *stream) 218 { 219 SkMatrix matrix; 220 for (int i = 0; i < 9; i++) 221 matrix.set(i, stream->readScalar()); 222 return matrix; 223 } 224 225 void writeSkLength(SkWStream *stream, SkLength length) 226 { 227 stream->write32(length.type); 228 stream->writeScalar(length.value); 229 } 230 231 SkLength readSkLength(SkStream *stream) 232 { 233 SkLength len; 234 len.type = (SkLength::SkLengthType) stream->readU32(); 235 len.value = stream->readScalar(); 236 return len; 237 } 238 239 void writeSkRect(SkWStream *stream, SkRect rect) 240 { 241 stream->writeScalar(rect.fLeft); 242 stream->writeScalar(rect.fTop); 243 stream->writeScalar(rect.fRight); 244 stream->writeScalar(rect.fBottom); 245 } 246 247 SkRect readSkRect(SkStream *stream) 248 { 249 SkRect rect; 250 rect.fLeft = stream->readScalar(); 251 rect.fTop = stream->readScalar(); 252 rect.fRight = stream->readScalar(); 253 rect.fBottom = stream->readScalar(); 254 return rect; 255 } 256 257 void writeTransformationMatrix(SkWStream *stream, TransformationMatrix& matrix) 258 { 259 double value; 260 int dsize = sizeof(double); 261 value = matrix.m11(); 262 stream->write(&value, dsize); 263 value = matrix.m12(); 264 stream->write(&value, dsize); 265 value = matrix.m13(); 266 stream->write(&value, dsize); 267 value = matrix.m14(); 268 stream->write(&value, dsize); 269 value = matrix.m21(); 270 stream->write(&value, dsize); 271 value = matrix.m22(); 272 stream->write(&value, dsize); 273 value = matrix.m23(); 274 stream->write(&value, dsize); 275 value = matrix.m24(); 276 stream->write(&value, dsize); 277 value = matrix.m31(); 278 stream->write(&value, dsize); 279 value = matrix.m32(); 280 stream->write(&value, dsize); 281 value = matrix.m33(); 282 stream->write(&value, dsize); 283 value = matrix.m34(); 284 stream->write(&value, dsize); 285 value = matrix.m41(); 286 stream->write(&value, dsize); 287 value = matrix.m42(); 288 stream->write(&value, dsize); 289 value = matrix.m43(); 290 stream->write(&value, dsize); 291 value = matrix.m44(); 292 stream->write(&value, dsize); 293 } 294 295 void readTransformationMatrix(SkStream *stream, TransformationMatrix& matrix) 296 { 297 double value; 298 int dsize = sizeof(double); 299 stream->read(&value, dsize); 300 matrix.setM11(value); 301 stream->read(&value, dsize); 302 matrix.setM12(value); 303 stream->read(&value, dsize); 304 matrix.setM13(value); 305 stream->read(&value, dsize); 306 matrix.setM14(value); 307 stream->read(&value, dsize); 308 matrix.setM21(value); 309 stream->read(&value, dsize); 310 matrix.setM22(value); 311 stream->read(&value, dsize); 312 matrix.setM23(value); 313 stream->read(&value, dsize); 314 matrix.setM24(value); 315 stream->read(&value, dsize); 316 matrix.setM31(value); 317 stream->read(&value, dsize); 318 matrix.setM32(value); 319 stream->read(&value, dsize); 320 matrix.setM33(value); 321 stream->read(&value, dsize); 322 matrix.setM34(value); 323 stream->read(&value, dsize); 324 matrix.setM41(value); 325 stream->read(&value, dsize); 326 matrix.setM42(value); 327 stream->read(&value, dsize); 328 matrix.setM43(value); 329 stream->read(&value, dsize); 330 matrix.setM44(value); 331 } 332 333 void serializeLayer(LayerAndroid* layer, SkWStream* stream) 334 { 335 if (!layer) { 336 ALOGV("NULL layer!"); 337 stream->write8(LTNone); 338 return; 339 } 340 if (layer->isMedia() || layer->isVideo()) { 341 ALOGV("Layer isn't supported for serialization: isMedia: %s, isVideo: %s", 342 layer->isMedia() ? "true" : "false", 343 layer->isVideo() ? "true" : "false"); 344 stream->write8(LTNone); 345 return; 346 } 347 LayerTypes type = LTLayerAndroid; 348 if (layer->contentIsScrollable()) 349 type = LTScrollableLayerAndroid; 350 stream->write8(type); 351 352 // Start with Layer fields 353 stream->writeBool(layer->shouldInheritFromRootTransform()); 354 stream->writeScalar(layer->getOpacity()); 355 stream->writeScalar(layer->getSize().width()); 356 stream->writeScalar(layer->getSize().height()); 357 stream->writeScalar(layer->getPosition().x()); 358 stream->writeScalar(layer->getPosition().y()); 359 stream->writeScalar(layer->getAnchorPoint().x()); 360 stream->writeScalar(layer->getAnchorPoint().y()); 361 writeMatrix(stream, layer->getMatrix()); 362 writeMatrix(stream, layer->getChildrenMatrix()); 363 364 // Next up, LayerAndroid fields 365 stream->writeBool(layer->m_haveClip); 366 stream->writeBool(layer->isPositionFixed()); 367 stream->writeBool(layer->m_backgroundColorSet); 368 stream->writeBool(layer->isIFrame()); 369 370 // With the current LayerAndroid hierarchy, LayerAndroid doesn't have 371 // those fields anymore. Let's keep the current serialization format for 372 // now and output blank fields... not great, but probably better than 373 // dealing with multiple versions. 374 if (layer->fixedPosition()) { 375 FixedPositioning* fixedPosition = layer->fixedPosition(); 376 writeSkLength(stream, fixedPosition->m_fixedLeft); 377 writeSkLength(stream, fixedPosition->m_fixedTop); 378 writeSkLength(stream, fixedPosition->m_fixedRight); 379 writeSkLength(stream, fixedPosition->m_fixedBottom); 380 writeSkLength(stream, fixedPosition->m_fixedMarginLeft); 381 writeSkLength(stream, fixedPosition->m_fixedMarginTop); 382 writeSkLength(stream, fixedPosition->m_fixedMarginRight); 383 writeSkLength(stream, fixedPosition->m_fixedMarginBottom); 384 writeSkRect(stream, fixedPosition->m_fixedRect); 385 stream->write32(fixedPosition->m_renderLayerPos.x()); 386 stream->write32(fixedPosition->m_renderLayerPos.y()); 387 } else { 388 SkLength length; 389 SkRect rect; 390 writeSkLength(stream, length); // fixedLeft 391 writeSkLength(stream, length); // fixedTop 392 writeSkLength(stream, length); // fixedRight 393 writeSkLength(stream, length); // fixedBottom 394 writeSkLength(stream, length); // fixedMarginLeft 395 writeSkLength(stream, length); // fixedMarginTop 396 writeSkLength(stream, length); // fixedMarginRight 397 writeSkLength(stream, length); // fixedMarginBottom 398 writeSkRect(stream, rect); // fixedRect 399 stream->write32(0); // renderLayerPos.x() 400 stream->write32(0); // renderLayerPos.y() 401 } 402 403 stream->writeBool(layer->m_backfaceVisibility); 404 stream->writeBool(layer->m_visible); 405 stream->write32(layer->m_backgroundColor); 406 stream->writeBool(layer->m_preserves3D); 407 stream->writeScalar(layer->m_anchorPointZ); 408 stream->writeScalar(layer->m_drawOpacity); 409 bool hasContentsImage = layer->m_imageCRC != 0; 410 stream->writeBool(hasContentsImage); 411 if (hasContentsImage) { 412 SkOrderedWriteBuffer buffer(1024); 413 buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag); 414 ImageTexture* imagetexture = 415 ImagesManager::instance()->retainImage(layer->m_imageCRC); 416 if (imagetexture && imagetexture->bitmap()) 417 imagetexture->bitmap()->flatten(buffer); 418 ImagesManager::instance()->releaseImage(layer->m_imageCRC); 419 stream->write32(buffer.size()); 420 buffer.writeToStream(stream); 421 } 422 bool hasRecordingPicture = layer->m_content != 0 && !layer->m_content->isEmpty(); 423 stream->writeBool(hasRecordingPicture); 424 if (hasRecordingPicture) 425 layer->m_content->serialize(stream); 426 // TODO: support m_animations (maybe?) 427 stream->write32(0); // placeholder for m_animations.size(); 428 writeTransformationMatrix(stream, layer->m_transform); 429 writeTransformationMatrix(stream, layer->m_childrenTransform); 430 if (type == LTScrollableLayerAndroid) { 431 ScrollableLayerAndroid* scrollableLayer = 432 static_cast<ScrollableLayerAndroid*>(layer); 433 stream->writeScalar(scrollableLayer->m_scrollLimits.fLeft); 434 stream->writeScalar(scrollableLayer->m_scrollLimits.fTop); 435 stream->writeScalar(scrollableLayer->m_scrollLimits.width()); 436 stream->writeScalar(scrollableLayer->m_scrollLimits.height()); 437 } 438 int childCount = layer->countChildren(); 439 stream->write32(childCount); 440 for (int i = 0; i < childCount; i++) 441 serializeLayer(layer->getChild(i), stream); 442 } 443 444 LayerAndroid* deserializeLayer(int version, SkMemoryStream* stream) 445 { 446 int type = stream->readU8(); 447 if (type == LTNone) 448 return 0; 449 // Cast is to disambiguate between ctors. 450 LayerAndroid *layer; 451 if (type == LTLayerAndroid) 452 layer = new LayerAndroid((RenderLayer*) 0); 453 else if (type == LTScrollableLayerAndroid) 454 layer = new ScrollableLayerAndroid((RenderLayer*) 0); 455 else { 456 ALOGV("Unexpected layer type: %d, aborting!", type); 457 return 0; 458 } 459 460 // Layer fields 461 layer->setShouldInheritFromRootTransform(stream->readBool()); 462 layer->setOpacity(stream->readScalar()); 463 layer->setSize(stream->readScalar(), stream->readScalar()); 464 layer->setPosition(stream->readScalar(), stream->readScalar()); 465 layer->setAnchorPoint(stream->readScalar(), stream->readScalar()); 466 layer->setMatrix(readMatrix(stream)); 467 layer->setChildrenMatrix(readMatrix(stream)); 468 469 // LayerAndroid fields 470 layer->m_haveClip = stream->readBool(); 471 472 // Keep the legacy serialization/deserialization format... 473 bool isFixed = stream->readBool(); 474 475 layer->m_backgroundColorSet = stream->readBool(); 476 477 bool isIframe = stream->readBool(); 478 // If we are a scrollable layer android, we are an iframe content 479 if (isIframe && type == LTScrollableLayerAndroid) { 480 IFrameContentLayerAndroid* iframeContent = new IFrameContentLayerAndroid(*layer); 481 layer->unref(); 482 layer = iframeContent; 483 } else if (isIframe) { // otherwise we are just the iframe (we use it to compute offset) 484 IFrameLayerAndroid* iframe = new IFrameLayerAndroid(*layer); 485 layer->unref(); 486 layer = iframe; 487 } 488 489 if (isFixed) { 490 FixedPositioning* fixedPosition = new FixedPositioning(layer); 491 492 fixedPosition->m_fixedLeft = readSkLength(stream); 493 fixedPosition->m_fixedTop = readSkLength(stream); 494 fixedPosition->m_fixedRight = readSkLength(stream); 495 fixedPosition->m_fixedBottom = readSkLength(stream); 496 fixedPosition->m_fixedMarginLeft = readSkLength(stream); 497 fixedPosition->m_fixedMarginTop = readSkLength(stream); 498 fixedPosition->m_fixedMarginRight = readSkLength(stream); 499 fixedPosition->m_fixedMarginBottom = readSkLength(stream); 500 fixedPosition->m_fixedRect = readSkRect(stream); 501 fixedPosition->m_renderLayerPos.setX(stream->readS32()); 502 fixedPosition->m_renderLayerPos.setY(stream->readS32()); 503 504 layer->setFixedPosition(fixedPosition); 505 } else { 506 // Not a fixed element, bypass the values in the stream 507 readSkLength(stream); // fixedLeft 508 readSkLength(stream); // fixedTop 509 readSkLength(stream); // fixedRight 510 readSkLength(stream); // fixedBottom 511 readSkLength(stream); // fixedMarginLeft 512 readSkLength(stream); // fixedMarginTop 513 readSkLength(stream); // fixedMarginRight 514 readSkLength(stream); // fixedMarginBottom 515 readSkRect(stream); // fixedRect 516 stream->readS32(); // renderLayerPos.x() 517 stream->readS32(); // renderLayerPos.y() 518 } 519 520 layer->m_backfaceVisibility = stream->readBool(); 521 layer->m_visible = stream->readBool(); 522 layer->m_backgroundColor = stream->readU32(); 523 layer->m_preserves3D = stream->readBool(); 524 layer->m_anchorPointZ = stream->readScalar(); 525 layer->m_drawOpacity = stream->readScalar(); 526 bool hasContentsImage = stream->readBool(); 527 if (hasContentsImage) { 528 int size = stream->readU32(); 529 SkAutoMalloc storage(size); 530 stream->read(storage.get(), size); 531 SkOrderedReadBuffer buffer(storage.get(), size); 532 SkBitmap contentsImage; 533 contentsImage.unflatten(buffer); 534 SkBitmapRef* imageRef = new SkBitmapRef(contentsImage); 535 layer->setContentsImage(imageRef); 536 delete imageRef; 537 } 538 bool hasRecordingPicture = stream->readBool(); 539 if (hasRecordingPicture) { 540 LayerContent* content; 541 if (version == 1) { 542 content = new LegacyPictureLayerContent(stream); 543 } else { 544 SkPicture* picture = new SkPicture(stream); 545 content = new PictureLayerContent(picture); 546 SkSafeUnref(picture); 547 } 548 layer->setContent(content); 549 SkSafeUnref(content); 550 } 551 int animationCount = stream->readU32(); // TODO: Support (maybe?) 552 readTransformationMatrix(stream, layer->m_transform); 553 readTransformationMatrix(stream, layer->m_childrenTransform); 554 if (type == LTScrollableLayerAndroid) { 555 ScrollableLayerAndroid* scrollableLayer = 556 static_cast<ScrollableLayerAndroid*>(layer); 557 scrollableLayer->m_scrollLimits.set( 558 stream->readScalar(), 559 stream->readScalar(), 560 stream->readScalar(), 561 stream->readScalar()); 562 } 563 int childCount = stream->readU32(); 564 for (int i = 0; i < childCount; i++) { 565 LayerAndroid *childLayer = deserializeLayer(version, stream); 566 if (childLayer) 567 layer->addChild(childLayer); 568 } 569 ALOGV("Created layer with id %d", layer->uniqueId()); 570 return layer; 571 } 572 573 /* 574 * JNI registration 575 */ 576 static JNINativeMethod gSerializerMethods[] = { 577 { "nativeDumpLayerHierarchy", "(IILjava/io/OutputStream;[B)V", 578 (void*) nativeDumpLayerHierarchy }, 579 { "nativeSerializeViewState", "(ILjava/io/OutputStream;[B)Z", 580 (void*) nativeSerializeViewState }, 581 { "nativeDeserializeViewState", "(ILjava/io/InputStream;[B)I", 582 (void*) nativeDeserializeViewState }, 583 }; 584 585 int registerViewStateSerializer(JNIEnv* env) 586 { 587 return jniRegisterNativeMethods(env, "android/webkit/ViewStateSerializer", 588 gSerializerMethods, NELEM(gSerializerMethods)); 589 } 590 591 } 592