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