blob: 6cf3c3aed720526d578280ff704188fb061d08c2 [file] [log] [blame]
msarett95f192d2015-02-13 09:05:41 -08001/*
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 "DecodingBench.h"
scroggo21027992015-04-02 13:22:38 -07009#include "SkBitmap.h"
msarett95f192d2015-02-13 09:05:41 -080010#include "SkData.h"
11#include "SkImageDecoder.h"
scroggo60869a42015-04-01 12:09:17 -070012#include "SkMallocPixelRef.h"
msarett95f192d2015-02-13 09:05:41 -080013#include "SkOSFile.h"
14#include "SkStream.h"
15
16/*
17 *
18 * This benchmark is designed to test the performance of image decoding.
19 * It is invoked from the nanobench.cpp file.
20 *
21 */
22DecodingBench::DecodingBench(SkString path, SkColorType colorType)
23 : fColorType(colorType)
scroggo60869a42015-04-01 12:09:17 -070024 , fData(SkData::NewFromFileName(path.c_str()))
msarett95f192d2015-02-13 09:05:41 -080025{
26 // Parse filename and the color type to give the benchmark a useful name
27 SkString baseName = SkOSPath::Basename(path.c_str());
28 const char* colorName;
29 switch(colorType) {
30 case kN32_SkColorType:
31 colorName = "N32";
32 break;
33 case kRGB_565_SkColorType:
34 colorName = "565";
35 break;
36 case kAlpha_8_SkColorType:
37 colorName = "Alpha8";
38 break;
39 default:
40 colorName = "Unknown";
41 }
42 fName.printf("Decode_%s_%s", baseName.c_str(), colorName);
43
scroggo60869a42015-04-01 12:09:17 -070044#ifdef SK_DEBUG
45 // Ensure that we can create a decoder.
46 SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData));
47 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
48 SkASSERT(decoder != NULL);
49#endif
msarett95f192d2015-02-13 09:05:41 -080050}
51
52const char* DecodingBench::onGetName() {
53 return fName.c_str();
54}
55
56bool DecodingBench::isSuitableFor(Backend backend) {
57 return kNonRendering_Backend == backend;
58}
59
scroggo60869a42015-04-01 12:09:17 -070060void DecodingBench::onPreDraw() {
61 // Allocate the pixels now, to remove it from the loop.
62 SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData));
63 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
scroggo21027992015-04-02 13:22:38 -070064 SkBitmap bm;
scroggo60869a42015-04-01 12:09:17 -070065#ifdef SK_DEBUG
66 SkImageDecoder::Result result =
67#endif
scroggo21027992015-04-02 13:22:38 -070068 decoder->decode(stream, &bm, fColorType, SkImageDecoder::kDecodeBounds_Mode);
scroggo60869a42015-04-01 12:09:17 -070069 SkASSERT(SkImageDecoder::kFailure != result);
scroggo21027992015-04-02 13:22:38 -070070
71 const size_t rowBytes = bm.info().minRowBytes();
72 fPixelStorage.reset(bm.info().getSafeSize(rowBytes));
scroggo60869a42015-04-01 12:09:17 -070073}
74
scroggo21027992015-04-02 13:22:38 -070075// Allocator which just uses an existing block of memory.
76class TargetAllocator : public SkBitmap::Allocator {
scroggo60869a42015-04-01 12:09:17 -070077public:
scroggo21027992015-04-02 13:22:38 -070078 explicit TargetAllocator(void* storage)
79 : fPixelStorage(storage) {}
scroggo60869a42015-04-01 12:09:17 -070080
81 bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override {
scroggo21027992015-04-02 13:22:38 -070082 // We depend on the fact that this will only ever be used to
83 // decode to a bitmap with the same settings used to create
84 // fPixelStorage.
scroggo60869a42015-04-01 12:09:17 -070085 bm->setPixelRef(SkMallocPixelRef::NewDirect(bm->info(),
scroggo21027992015-04-02 13:22:38 -070086 fPixelStorage, bm->rowBytes(), ct))->unref();
scroggo60869a42015-04-01 12:09:17 -070087 return true;
88 }
89
90private:
scroggo21027992015-04-02 13:22:38 -070091 void* fPixelStorage; // Unowned. DecodingBench owns this.
scroggo60869a42015-04-01 12:09:17 -070092};
93
msarett95f192d2015-02-13 09:05:41 -080094void DecodingBench::onDraw(const int n, SkCanvas* canvas) {
95 SkBitmap bitmap;
scroggo60869a42015-04-01 12:09:17 -070096 // Declare the allocator before the decoder, so it will outlive the
97 // decoder, which will unref it.
scroggo21027992015-04-02 13:22:38 -070098 TargetAllocator allocator(fPixelStorage.get());
scroggo60869a42015-04-01 12:09:17 -070099 SkAutoTDelete<SkImageDecoder> decoder;
100 SkAutoTDelete<SkStreamRewindable> stream;
msarett95f192d2015-02-13 09:05:41 -0800101 for (int i = 0; i < n; i++) {
scroggo60869a42015-04-01 12:09:17 -0700102 // create a new stream and a new decoder to mimic the behavior of
103 // CodecBench.
104 stream.reset(new SkMemoryStream(fData));
105 decoder.reset(SkImageDecoder::Factory(stream));
106 decoder->setAllocator(&allocator);
107 decoder->decode(stream, &bitmap, fColorType,
108 SkImageDecoder::kDecodePixels_Mode);
msarett95f192d2015-02-13 09:05:41 -0800109 }
110}