am 0b7e0b6a: Isolate Playback of SkPictures that we encoded with an older version of Skia.
* commit '0b7e0b6ac6ab34ea2d11b4891ca91f359e231cfe':
Isolate Playback of SkPictures that we encoded with an older version of Skia.
diff --git a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
index ac838c8..5b22488 100644
--- a/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
+++ b/Source/WebCore/platform/graphics/android/layers/FixedPositioning.h
@@ -134,7 +134,7 @@
// ViewStateSerializer friends
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
- friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkMemoryStream* stream);
protected:
LayerAndroid* m_layer;
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 6c2e43d..dc844b3 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -58,7 +58,7 @@
namespace android {
class DrawExtra;
void serializeLayer(WebCore::LayerAndroid* layer, SkWStream* stream);
-WebCore::LayerAndroid* deserializeLayer(int version, SkStream* stream);
+WebCore::LayerAndroid* deserializeLayer(int version, SkMemoryStream* stream);
void cleanupImageRefs(WebCore::LayerAndroid* layer);
}
@@ -256,7 +256,7 @@
// ViewStateSerializer friends
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
- friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkMemoryStream* stream);
friend void android::cleanupImageRefs(LayerAndroid* layer);
LayerType type() { return m_type; }
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
index 54f7979..4aeab01 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
@@ -8,6 +8,9 @@
#include "InspectorCanvas.h"
#include "SkPicture.h"
+#include <dlfcn.h>
+#include "SkDevice.h"
+
namespace WebCore {
PictureLayerContent::PictureLayerContent(SkPicture* picture)
@@ -97,4 +100,71 @@
m_picture->serialize(stream);
}
+
+LegacyPictureLayerContent::LegacyPictureLayerContent(SkMemoryStream* pictureStream) {
+ m_legacyPicture = NULL;
+ m_width = 0;
+ m_height = 0;
+
+ // load legacy skia lib (all functions hidden except ones defined below)
+ m_legacyLib = dlopen("libskia_legacy.so", RTLD_LAZY);
+ *reinterpret_cast<void**>(&m_createPictureProc) = dlsym(m_legacyLib, "legacy_skia_create_picture");
+ *reinterpret_cast<void**>(&m_deletePictureProc) = dlsym(m_legacyLib, "legacy_skia_delete_picture");
+ *reinterpret_cast<void**>(&m_drawPictureProc) = dlsym(m_legacyLib, "legacy_skia_draw_picture");
+
+ const char* error = dlerror();
+ if (error) {
+ SkDebugf("Unable to load legacy lib: %s", error);
+ sk_throw();
+ }
+
+ // call into library to create picture and set width and height
+ const int streamLength = pictureStream->getLength() - pictureStream->peek();
+ int bytesRead = m_createPictureProc(pictureStream->getAtPos(), streamLength,
+ &m_legacyPicture, &m_width, &m_height);
+ pictureStream->skip(bytesRead);
+}
+
+LegacyPictureLayerContent::~LegacyPictureLayerContent() {
+ if (m_legacyLib) {
+ if (m_legacyPicture) {
+ m_deletePictureProc(m_legacyPicture);
+ }
+ dlclose(m_legacyLib);
+ }
+}
+
+void LegacyPictureLayerContent::draw(SkCanvas* canvas) {
+ if (!m_legacyPicture) {
+ return;
+ }
+
+ // if this is an InspectorCanvas we need to at least draw something to
+ // ensure that the canvas is not discarded. (We perform a no-op text
+ // draw in order to trigger the InspectorCanvas into performing high
+ // fidelity rendering while zooming.
+ SkPaint paint;
+ canvas->drawText(NULL, 0, 0, 0, paint);
+
+ // decompose the canvas into basics
+ void* matrixStorage = malloc(canvas->getTotalMatrix().flatten(NULL));
+ void* clipStorage = malloc(canvas->getTotalClip().flatten(NULL));
+
+ canvas->getTotalMatrix().flatten(matrixStorage);
+ canvas->getTotalClip().flatten(clipStorage);
+
+ const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true);
+ bitmap.lockPixels();
+
+ // pass picture, matrix, clip, and bitmap
+ m_drawPictureProc(m_legacyPicture, matrixStorage, clipStorage,
+ bitmap.width(), bitmap.height(), bitmap.getConfig(),
+ bitmap.rowBytes(), bitmap.getPixels());
+
+
+ bitmap.unlockPixels();
+ free(matrixStorage);
+ free(clipStorage);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
index e5181a5..bb004f2 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
@@ -27,6 +27,7 @@
#define PictureLayerContent_h
#include "LayerContent.h"
+#include "SkStream.h"
namespace WebCore {
@@ -50,6 +51,34 @@
bool m_hasText;
};
+class LegacyPictureLayerContent : public LayerContent {
+public:
+ LegacyPictureLayerContent(SkMemoryStream* pictureStream);
+ ~LegacyPictureLayerContent();
+
+ virtual int width() { return m_width; }
+ virtual int height() { return m_height; }
+ virtual void setCheckForOptimisations(bool check) {}
+ virtual void checkForOptimisations() {}
+ virtual float maxZoomScale() { return 1e6; }
+ virtual void draw(SkCanvas* canvas);
+ virtual void serialize(SkWStream* stream) { }
+
+private:
+ void* m_legacyLib;
+ void* m_legacyPicture;
+ int m_width;
+ int m_height;
+
+ typedef int (*legacy_skia_create_picture_proc)(const void*, int, void**, int*, int*);
+ typedef void (*legacy_skia_delete_picture_proc)(void*);
+ typedef void (*legacy_skia_draw_picture_proc)(void*, void*, void*, int, int, int, int, void*);
+
+ legacy_skia_create_picture_proc m_createPictureProc;
+ legacy_skia_delete_picture_proc m_deletePictureProc;
+ legacy_skia_draw_picture_proc m_drawPictureProc;
+};
+
} // WebCore
#endif // PictureLayerContent_h
diff --git a/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
index b3c828f..4f76274 100644
--- a/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/ScrollableLayerAndroid.h
@@ -64,7 +64,7 @@
bool scrollRectIntoView(const SkIRect&);
friend void android::serializeLayer(LayerAndroid* layer, SkWStream* stream);
- friend LayerAndroid* android::deserializeLayer(int version, SkStream* stream);
+ friend LayerAndroid* android::deserializeLayer(int version, SkMemoryStream* stream);
protected:
diff --git a/Source/WebKit/android/jni/ViewStateSerializer.cpp b/Source/WebKit/android/jni/ViewStateSerializer.cpp
index ebbccfe..ff7d728 100644
--- a/Source/WebKit/android/jni/ViewStateSerializer.cpp
+++ b/Source/WebKit/android/jni/ViewStateSerializer.cpp
@@ -153,12 +153,40 @@
static BaseLayerAndroid* nativeDeserializeViewState(JNIEnv* env, jobject, jint version,
jobject jstream, jbyteArray jstorage)
{
- SkStream* stream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
- if (!stream)
+ SkStream* javaStream = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
+ if (!javaStream)
return 0;
- Color color = stream->readU32();
- SkPicture* picture = new SkPicture(stream);
- PictureLayerContent* content = new PictureLayerContent(picture);
+
+ // read everything into memory so that we can get the offset into the stream
+ // when necessary. This is needed for the LegacyPictureLayerContent.
+ SkDynamicMemoryWStream tempStream;
+ const int bufferSize = 256*1024; // 256KB
+ uint8_t buffer[bufferSize];
+ int bytesRead = 0;
+
+ do {
+ bytesRead = javaStream->read(buffer, bufferSize);
+ tempStream.write(buffer, bytesRead);
+ } while (bytesRead != 0);
+
+ SkMemoryStream stream;
+ stream.setData(tempStream.copyToData())->unref();
+
+ // clean up the javaStream now that we have everything in memory
+ delete javaStream;
+
+ Color color = stream.readU32();
+
+
+
+ LayerContent* content;
+ if (version == 1) {
+ content = new LegacyPictureLayerContent(&stream);
+ } else {
+ SkPicture* picture = new SkPicture(&stream);
+ content = new PictureLayerContent(picture);
+ SkSafeUnref(picture);
+ }
BaseLayerAndroid* layer = new BaseLayerAndroid(content);
layer->setBackgroundColor(color);
@@ -168,14 +196,12 @@
layer->markAsDirty(dirtyRegion);
SkSafeUnref(content);
- SkSafeUnref(picture);
- int childCount = stream->readS32();
+ int childCount = stream.readS32();
for (int i = 0; i < childCount; i++) {
- LayerAndroid* childLayer = deserializeLayer(version, stream);
+ LayerAndroid* childLayer = deserializeLayer(version, &stream);
if (childLayer)
layer->addChild(childLayer);
}
- delete stream;
return layer;
}
@@ -414,7 +440,7 @@
serializeLayer(layer->getChild(i), stream);
}
-LayerAndroid* deserializeLayer(int version, SkStream* stream)
+LayerAndroid* deserializeLayer(int version, SkMemoryStream* stream)
{
int type = stream->readU8();
if (type == LTNone)
@@ -510,11 +536,16 @@
}
bool hasRecordingPicture = stream->readBool();
if (hasRecordingPicture) {
- SkPicture* picture = new SkPicture(stream);
- PictureLayerContent* content = new PictureLayerContent(picture);
+ LayerContent* content;
+ if (version == 1) {
+ content = new LegacyPictureLayerContent(stream);
+ } else {
+ SkPicture* picture = new SkPicture(stream);
+ content = new PictureLayerContent(picture);
+ SkSafeUnref(picture);
+ }
layer->setContent(content);
SkSafeUnref(content);
- SkSafeUnref(picture);
}
int animationCount = stream->readU32(); // TODO: Support (maybe?)
readTransformationMatrix(stream, layer->m_transform);