OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "CodecBenchPriv.h" | |
9 #include "DecodingBench.h" | |
10 #include "SkBitmap.h" | |
11 #include "SkData.h" | |
12 #include "SkImageDecoder.h" | |
13 #include "SkMallocPixelRef.h" | |
14 #include "SkOSFile.h" | |
15 #include "SkStream.h" | |
16 | |
17 /* | |
18 * | |
19 * This benchmark is designed to test the performance of image decoding. | |
20 * It is invoked from the nanobench.cpp file. | |
21 * | |
22 */ | |
23 DecodingBench::DecodingBench(SkString path, SkColorType colorType) | |
24 : fColorType(colorType) | |
25 , fData(SkData::NewFromFileName(path.c_str())) | |
26 { | |
27 // Parse filename and the color type to give the benchmark a useful name | |
28 SkString baseName = SkOSPath::Basename(path.c_str()); | |
29 fName.printf("Decode_%s_%s", baseName.c_str(), color_type_to_str(colorType))
; | |
30 | |
31 #ifdef SK_DEBUG | |
32 // Ensure that we can create a decoder. | |
33 SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData)); | |
34 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); | |
35 SkASSERT(decoder != nullptr); | |
36 #endif | |
37 } | |
38 | |
39 const char* DecodingBench::onGetName() { | |
40 return fName.c_str(); | |
41 } | |
42 | |
43 bool DecodingBench::isSuitableFor(Backend backend) { | |
44 return kNonRendering_Backend == backend; | |
45 } | |
46 | |
47 void DecodingBench::onDelayedSetup() { | |
48 // Allocate the pixels now, to remove it from the loop. | |
49 SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData)); | |
50 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); | |
51 SkBitmap bm; | |
52 #ifdef SK_DEBUG | |
53 SkImageDecoder::Result result = | |
54 #endif | |
55 decoder->decode(stream, &bm, fColorType, SkImageDecoder::kDecodeBounds_Mode)
; | |
56 SkASSERT(SkImageDecoder::kFailure != result); | |
57 | |
58 const size_t rowBytes = bm.info().minRowBytes(); | |
59 fPixelStorage.reset(bm.info().getSafeSize(rowBytes)); | |
60 } | |
61 | |
62 // Allocator which just uses an existing block of memory. | |
63 class TargetAllocator : public SkBitmap::Allocator { | |
64 public: | |
65 explicit TargetAllocator(void* storage) | |
66 : fPixelStorage(storage) {} | |
67 | |
68 bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override { | |
69 // We depend on the fact that this will only ever be used to | |
70 // decode to a bitmap with the same settings used to create | |
71 // fPixelStorage. | |
72 bm->setPixelRef(SkMallocPixelRef::NewDirect(bm->info(), | |
73 fPixelStorage, bm->rowBytes(), ct))->unref(); | |
74 return true; | |
75 } | |
76 | |
77 private: | |
78 void* fPixelStorage; // Unowned. DecodingBench owns this. | |
79 }; | |
80 | |
81 void DecodingBench::onDraw(int n, SkCanvas* canvas) { | |
82 SkBitmap bitmap; | |
83 // Declare the allocator before the decoder, so it will outlive the | |
84 // decoder, which will unref it. | |
85 TargetAllocator allocator(fPixelStorage.get()); | |
86 SkAutoTDelete<SkImageDecoder> decoder; | |
87 SkAutoTDelete<SkStreamRewindable> stream; | |
88 for (int i = 0; i < n; i++) { | |
89 // create a new stream and a new decoder to mimic the behavior of | |
90 // CodecBench. | |
91 stream.reset(new SkMemoryStream(fData)); | |
92 decoder.reset(SkImageDecoder::Factory(stream)); | |
93 decoder->setAllocator(&allocator); | |
94 decoder->decode(stream, &bitmap, fColorType, | |
95 SkImageDecoder::kDecodePixels_Mode); | |
96 } | |
97 } | |
OLD | NEW |