Index: bench/DecodingBench.cpp |
diff --git a/bench/DecodingBench.cpp b/bench/DecodingBench.cpp |
index c8490ca7a89cf2d91fa8f5aa0b4866d3ee5b18cd..63096c51de363a5cc8db9cacefab1afef5d753a1 100644 |
--- a/bench/DecodingBench.cpp |
+++ b/bench/DecodingBench.cpp |
@@ -8,7 +8,9 @@ |
#include "DecodingBench.h" |
#include "SkData.h" |
#include "SkImageDecoder.h" |
+#include "SkMallocPixelRef.h" |
#include "SkOSFile.h" |
+#include "SkPixelRef.h" |
#include "SkStream.h" |
/* |
@@ -41,7 +43,11 @@ DecodingBench::DecodingBench(SkString path, SkColorType colorType) |
// Perform setup for the decode |
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); |
fStream.reset(new SkMemoryStream(encoded)); |
- fDecoder.reset(SkImageDecoder::Factory(fStream.get())); |
+#ifdef SK_DEBUG |
+ // Ensure that we can create a decoder. |
+ SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); |
+ SkASSERT(decoder != NULL); |
djsollen
2015/04/01 17:23:50
move this to line 64.
scroggo
2015/04/01 17:40:54
Again, do you think doing less work here is better
|
+#endif |
} |
const char* DecodingBench::onGetName() { |
@@ -52,11 +58,51 @@ bool DecodingBench::isSuitableFor(Backend backend) { |
return kNonRendering_Backend == backend; |
} |
+void DecodingBench::onPreDraw() { |
+ // Allocate the pixels now, to remove it from the loop. |
+ SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); |
+#ifdef SK_DEBUG |
+ SkImageDecoder::Result result = |
+#endif |
+ decoder->decode(fStream, &fBitmap, fColorType, |
+ SkImageDecoder::kDecodeBounds_Mode); |
+ SkASSERT(SkImageDecoder::kFailure != result); |
+ fBitmap.allocPixels(fBitmap.info()); |
+} |
+ |
+// Allocator which just reuses the pixels from an existing SkPixelRef. |
+class UseExistingAllocator : public SkBitmap::Allocator { |
+public: |
+ explicit UseExistingAllocator(SkPixelRef* pr) |
+ : fPixelRef(SkRef(pr)) {} |
+ |
+ bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override { |
+ // We depend on the fact that fPixelRef is an SkMallocPixelRef, which |
+ // is always locked, and the fact that this will only ever be used to |
+ // decode to a bitmap with the same settings used to create the |
+ // original pixel ref. |
+ bm->setPixelRef(SkMallocPixelRef::NewDirect(bm->info(), |
+ fPixelRef->pixels(), bm->rowBytes(), ct))->unref(); |
+ return true; |
+ } |
+ |
+private: |
+ SkAutoTUnref<SkPixelRef> fPixelRef; |
+}; |
+ |
void DecodingBench::onDraw(const int n, SkCanvas* canvas) { |
SkBitmap bitmap; |
+ // Declare the allocator before the decoder, so it will outlive the |
+ // decoder, which will unref it. |
+ UseExistingAllocator allocator(fBitmap.pixelRef()); |
+ SkAutoTDelete<SkImageDecoder> decoder; |
+ SkAutoTDelete<SkStreamRewindable> stream; |
for (int i = 0; i < n; i++) { |
- fStream->rewind(); |
- fDecoder->decode(fStream, &bitmap, fColorType, |
- SkImageDecoder::kDecodePixels_Mode); |
+ // duplicate the stream and create a new decoder to mimic the behavior of CodecBench. |
+ stream.reset(fStream->duplicate()); |
+ decoder.reset(SkImageDecoder::Factory(stream)); |
+ decoder->setAllocator(&allocator); |
+ decoder->decode(stream, &bitmap, fColorType, |
+ SkImageDecoder::kDecodePixels_Mode); |
} |
} |