Skip to content

Instantly share code, notes, and snippets.

@astojilj
Created January 12, 2016 09:48
Show Gist options
  • Save astojilj/249ecfe421dd3af95314 to your computer and use it in GitHub Desktop.
Save astojilj/249ecfe421dd3af95314 to your computer and use it in GitHub Desktop.
Issue 507273 measurements patch
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index 09f931b..a9a80e0 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -294,7 +294,7 @@ SkBitmap ImageFrameGenerator::tryToResumeDecode(size_t index, const SkISize& sca
if (*it)
decodedFrameCount++;
}
- removeDecoder = m_frameCount && (decodedFrameCount == m_frameCount);
+ removeDecoder = m_frameCount && (decodedFrameCount == m_frameCount) && (index == m_frameCount - 1);
} else {
removeDecoder = complete;
}
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
index b660c66..3656b07 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -194,6 +194,22 @@ size_t ImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
return frameBytesCleared;
}
+size_t ImageDecoder::clearCacheExceptFrames(const HashSet<size_t>& clearExceptFrames)
+{
+ // Don't clear if there are no frames or only one frame.
+ if (m_frameBufferCache.size() <= 1)
+ return 0;
+
+ size_t frameBytesCleared = 0;
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i) {
+ if (m_frameBufferCache[i].status() != ImageFrame::FrameEmpty && !clearExceptFrames.contains(i)) {
+ frameBytesCleared += frameBytesAtIndex(i);
+ clearFrameBuffer(i);
+ }
+ }
+ return frameBytesCleared;
+}
+
void ImageDecoder::clearFrameBuffer(size_t frameIndex)
{
m_frameBufferCache[frameIndex].clearPixelData();
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
index 2ebd779..77a47eb 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -35,6 +35,7 @@
#include "platform/image-decoders/ImageFrame.h"
#include "public/platform/Platform.h"
#include "wtf/Assertions.h"
+#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Threading.h"
@@ -334,6 +335,12 @@ protected:
// Decodes the requested frame.
virtual void decode(size_t) = 0;
+ // Clears decoded pixel data from all frames except the provided frames.
+ // Callers may pass WTF::kNotFound to clear all frames.
+ // Note: If |m_frameBufferCache| contains only one frame, it won't be cleared.
+ // Returns the number of bytes of frame data actually cleared.
+ size_t clearCacheExceptFrames(const HashSet<size_t>&);
+
RefPtr<SharedBuffer> m_data; // The encoded data.
Vector<ImageFrame, 1> m_frameBufferCache;
bool m_premultiplyAlpha;
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
index cc5954e..566c581 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -218,10 +218,56 @@ bool GIFImageDecoder::frameComplete(size_t frameIndex)
return true;
}
+#define SKGR_DEBUG
+#ifdef SKGR_DEBUG
+
+#include <android/log.h>
+
+#include <time.h>
+
+using namespace std;
+static double elapsed(timespec start, timespec end)
+{
+ return (end.tv_sec-start.tv_sec)*1000 + (end.tv_nsec-start.tv_nsec) * 0.000001;
+}
+
+#define ELAPSE_START timespec time1, time2; clock_gettime(CLOCK_MONOTONIC, &time1);double elapsedMiliseconds;
+
+#define ELAPSE_END(a, ...) clock_gettime(CLOCK_MONOTONIC, &time2); \
+ elapsedMiliseconds = elapsed(time1, time2); \
+ __android_log_print(ANDROID_LOG_INFO, a, "took %fms for %d*%d frame %d depends on %d", elapsedMiliseconds, __VA_ARGS__); \
+ clock_gettime(CLOCK_MONOTONIC, &time1);
+#else
+#define ELAPSE_START
+#define ELAPSE_END(a, ...)
+#endif
+
+
size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
{
// We need to preserve frames such that:
// 1. We don't clear |clearExceptFrame|;
+ // 2. We don't clear any frame from which a two* future initFrameBuffer() calls
+ // will copy bitmap data.
+ // All other frames can be cleared.
+ // *) Two frames range is chosen as dependent animated GIF frames usually depend
+ // on the previous or the frame before previous.
+ HashSet<size_t> clearExceptFrames;
+ for (int i = 0; i < 2; ++i, ++clearExceptFrame) {
+ size_t leave = clearExceptFrame;
+ while ((leave < m_frameBufferCache.size()) && (m_frameBufferCache[leave].status() == ImageFrame::FrameEmpty))
+ leave = m_frameBufferCache[leave].requiredPreviousFrameIndex();
+ clearExceptFrames.add(leave);
+ }
+ if (clearExceptFrames.size() > 1)
+ return clearCacheExceptFrames(clearExceptFrames);
+ return ImageDecoder::clearCacheExceptFrame(*(clearExceptFrames.begin()));
+}
+
+/*size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
+{
+ // We need to preserve frames such that:
+ // 1. We don't clear |clearExceptFrame|;
// 2. We don't clear any frame from which a future initFrameBuffer() call
// will copy bitmap data.
// All other frames can be cleared.
@@ -229,7 +275,7 @@ size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPreviousFrameIndex();
return ImageDecoder::clearCacheExceptFrame(clearExceptFrame);
-}
+}*/
void GIFImageDecoder::clearFrameBuffer(size_t frameIndex)
{
@@ -263,6 +309,7 @@ void GIFImageDecoder::initializeNewFrame(size_t index)
void GIFImageDecoder::decode(size_t index)
{
+ ELAPSE_START
parse(GIFFrameCountQuery);
if (failed())
@@ -284,12 +331,14 @@ void GIFImageDecoder::decode(size_t index)
// We need more data to continue decoding.
if (m_frameBufferCache[*i].status() != ImageFrame::FrameComplete)
break;
+ __android_log_print(ANDROID_LOG_INFO, " GFX", "decoding frame %d", *i);
}
// It is also a fatal error if all data is received and we have decoded all
// frames available but the file is truncated.
if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() && m_reader && !m_reader->parseCompleted())
setFailed();
+ ELAPSE_END("GFXGIF", m_frameBufferCache[index].bitmap().width(), m_frameBufferCache[index].bitmap().height(), index, m_frameBufferCache[index].requiredPreviousFrameIndex());
}
void GIFImageDecoder::parse(GIFParseQuery query)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment