changeset 9675:3f15f2e59063

8153148: Defer image decoding until WebCore requests ImageFrame Reviewed-by: kcr, peterz
author arajkumar
date Wed, 13 Apr 2016 12:36:43 -0700
parents e1688df54bdc
children ee0fda72a77a
files modules/web/src/main/java/com/sun/javafx/webkit/prism/WCImageDecoderImpl.java modules/web/src/main/native/Source/WebCore/platform/graphics/java/ImageSourceJava.cpp
diffstat 2 files changed, 39 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCImageDecoderImpl.java	Tue Apr 12 15:26:59 2016 -0700
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCImageDecoderImpl.java	Wed Apr 13 12:36:43 2016 -0700
@@ -54,6 +54,7 @@
     private int imageHeight = 0;
     private ImageFrame[] frames;
     private int frameCount = 0; // keeps frame count when decoded frames are temporarily destroyed
+    private boolean fullDataReceived = false;
     private boolean framesDecoded = false; // guards frames from repeated decoding
     private PrismImage[] images;
     private volatile byte[] data;
@@ -77,6 +78,7 @@
         destroyLoader();
         frames = null;
         images = null;
+        framesDecoded = false;
     }
 
     @Override protected String getFilenameExtension() {
@@ -84,10 +86,13 @@
         return ".img";
     }
 
+    private boolean imageSizeAvilable() {
+        return imageWidth > 0 && imageHeight > 0;
+    }
 
     @Override protected void addImageData(byte[] dataPortion) {
         if (dataPortion != null) {
-            framesDecoded = false;
+            fullDataReceived = false;
             if (data == null) {
                 data = Arrays.copyOf(dataPortion, dataPortion.length * 2);
                 dataSize = dataPortion.length;
@@ -99,15 +104,16 @@
                 System.arraycopy(dataPortion, 0, data, dataSize, dataPortion.length);
                 dataSize = newDataSize;
             }
-            startLoader(); // partial data received - decode frames in background
-        } else if (data != null && !framesDecoded) {
+            // Try to decode the partial data until we get image size.
+            if (!imageSizeAvilable()) {
+                loadFrames();
+            }
+        } else if (data != null && !fullDataReceived) {
             // null dataPortion means data completion
-            destroyLoader();
             if (data.length > dataSize) {
                 resizeDataArray(dataSize);
             }
-            setFrames(loadFrames()); // full data received - decode frames immediately
-            framesDecoded = true;
+            fullDataReceived = true;
         }
     }
 
@@ -279,8 +285,12 @@
     }
 
     private ImageFrame getImageFrame(int idx) {
-        if (frames == null && idx >=0 && getFrameCount() > idx) {
+        if (!fullDataReceived) {
+            startLoader();
+        } else if (fullDataReceived && !framesDecoded) {
+            destroyLoader();
             setFrames(loadFrames()); // re-decode frames if they have been destroyed
+            framesDecoded = true;
         }
         return (idx >= 0) && (this.frames != null) && (this.frames.length > idx)
                 ? this.frames[idx]
--- a/modules/web/src/main/native/Source/WebCore/platform/graphics/java/ImageSourceJava.cpp	Tue Apr 12 15:26:59 2016 -0700
+++ b/modules/web/src/main/native/Source/WebCore/platform/graphics/java/ImageSourceJava.cpp	Wed Apr 13 12:36:43 2016 -0700
@@ -77,24 +77,17 @@
         "([B)V");
     ASSERT(midAddImageData);
 
-    size_t dataSize = data->size();
-    if (dataSize) {
-        jbyte* pData = (jbyte*) data->data();
-        ASSERT(pData);
-
-        JLByteArray jArray( m_dataSize < dataSize
-            ? env->NewByteArray(dataSize - m_dataSize)
-            : NULL);
+    const char* segment;
+    while (unsigned length = data->getSomeData(segment, m_dataSize)) {
+        JLByteArray jArray(env->NewByteArray(length));
         if (jArray && !CheckAndClearException(env)) {
             // not OOME in Java
-            env->SetByteArrayRegion(jArray, 0, dataSize - m_dataSize, pData + m_dataSize);
+            env->SetByteArrayRegion(jArray, 0, length, (const jbyte*)segment);
             env->CallVoidMethod(m_decoder, midAddImageData, (jbyteArray)jArray);
-            if (!CheckAndClearException(env)) {
-                m_dataSize = dataSize;
-            }
+            CheckAndClearException(env);
         }
+        m_dataSize += length;
     }
-
     if (allDataReceived) {
         env->CallVoidMethod(m_decoder, midAddImageData, 0);
         CheckAndClearException(env);
@@ -239,25 +232,25 @@
     SharedBuffer* data,
     bool allDataReceived)
 {
-        if (destroyAll) {
-                JNIEnv* env = WebCore_GetJavaEnv();
-                // [env] could be NULL in case of deallocation static BitmapImage objects
-                if (!env)
-                        return;
+    if (destroyAll) {
+        JNIEnv* env = WebCore_GetJavaEnv();
+        // [env] could be NULL in case of deallocation static BitmapImage objects
+        if (!env)
+            return;
 
-                static jmethodID midDestroy = env->GetMethodID(
-                        PG_GetGraphicsImageDecoderClass(env),
-                        "destroy",
-                        "()V");
-                ASSERT(midDestroy);
+        static jmethodID midDestroy = env->GetMethodID(
+                PG_GetGraphicsImageDecoderClass(env),
+                "destroy",
+                "()V");
+        ASSERT(midDestroy);
 
-                env->CallVoidMethod(m_decoder, midDestroy);
-                CheckAndClearException(env);
-        }
+        env->CallVoidMethod(m_decoder, midDestroy);
+        CheckAndClearException(env);
+    }
 
-        if (data) {
-                setData(data, allDataReceived);
-        }
+    if (data) {
+        setData(data, allDataReceived);
+    }
 }
 
 bool ImageSource::initialized() const