blob: 2feb7dd3efa3c17cdaecd959f1be6ffce559525a [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
msarett7f691442015-09-22 11:56:16 -07008#include "CodecBenchPriv.h"
msarett95f192d2015-02-13 09:05:41 -08009#include "DecodingBench.h"
scroggo21027992015-04-02 13:22:38 -070010#include "SkBitmap.h"
msarett95f192d2015-02-13 09:05:41 -080011#include "SkData.h"
12#include "SkImageDecoder.h"
scroggo60869a42015-04-01 12:09:17 -070013#include "SkMallocPixelRef.h"
msarett95f192d2015-02-13 09:05:41 -080014#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 */
23DecodingBench::DecodingBench(SkString path, SkColorType colorType)
24 : fColorType(colorType)
scroggo60869a42015-04-01 12:09:17 -070025 , fData(SkData::NewFromFileName(path.c_str()))
msarett95f192d2015-02-13 09:05:41 -080026{
27 // Parse filename and the color type to give the benchmark a useful name
28 SkString baseName = SkOSPath::Basename(path.c_str());
msarett7f691442015-09-22 11:56:16 -070029 fName.printf("Decode_%s_%s", baseName.c_str(), color_type_to_str(colorType));
mtkleina1ebeb22015-10-01 09:43:39 -070030
scroggo60869a42015-04-01 12:09:17 -070031#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));
halcanary96fcdcc2015-08-27 07:41:13 -070035 SkASSERT(decoder != nullptr);
scroggo60869a42015-04-01 12:09:17 -070036#endif
msarett95f192d2015-02-13 09:05:41 -080037}
38
39const char* DecodingBench::onGetName() {
40 return fName.c_str();
41}
42
43bool DecodingBench::isSuitableFor(Backend backend) {
44 return kNonRendering_Backend == backend;
45}
46
joshualitt8a6697a2015-09-30 12:11:07 -070047void DecodingBench::onDelayedSetup() {
scroggo60869a42015-04-01 12:09:17 -070048 // Allocate the pixels now, to remove it from the loop.
49 SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData));
50 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
scroggo21027992015-04-02 13:22:38 -070051 SkBitmap bm;
scroggo60869a42015-04-01 12:09:17 -070052#ifdef SK_DEBUG
53 SkImageDecoder::Result result =
54#endif
scroggo21027992015-04-02 13:22:38 -070055 decoder->decode(stream, &bm, fColorType, SkImageDecoder::kDecodeBounds_Mode);
scroggo60869a42015-04-01 12:09:17 -070056 SkASSERT(SkImageDecoder::kFailure != result);
scroggo21027992015-04-02 13:22:38 -070057
58 const size_t rowBytes = bm.info().minRowBytes();
59 fPixelStorage.reset(bm.info().getSafeSize(rowBytes));
scroggo60869a42015-04-01 12:09:17 -070060}
61
scroggo21027992015-04-02 13:22:38 -070062// Allocator which just uses an existing block of memory.
63class TargetAllocator : public SkBitmap::Allocator {
scroggo60869a42015-04-01 12:09:17 -070064public:
scroggo21027992015-04-02 13:22:38 -070065 explicit TargetAllocator(void* storage)
66 : fPixelStorage(storage) {}
scroggo60869a42015-04-01 12:09:17 -070067
68 bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override {
scroggo21027992015-04-02 13:22:38 -070069 // 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.
scroggo60869a42015-04-01 12:09:17 -070072 bm->setPixelRef(SkMallocPixelRef::NewDirect(bm->info(),
scroggo21027992015-04-02 13:22:38 -070073 fPixelStorage, bm->rowBytes(), ct))->unref();
scroggo60869a42015-04-01 12:09:17 -070074 return true;
75 }
76
77private:
scroggo21027992015-04-02 13:22:38 -070078 void* fPixelStorage; // Unowned. DecodingBench owns this.
scroggo60869a42015-04-01 12:09:17 -070079};
80
mtkleina1ebeb22015-10-01 09:43:39 -070081void DecodingBench::onDraw(int n, SkCanvas* canvas) {
msarett95f192d2015-02-13 09:05:41 -080082 SkBitmap bitmap;
scroggo60869a42015-04-01 12:09:17 -070083 // Declare the allocator before the decoder, so it will outlive the
84 // decoder, which will unref it.
scroggo21027992015-04-02 13:22:38 -070085 TargetAllocator allocator(fPixelStorage.get());
scroggo60869a42015-04-01 12:09:17 -070086 SkAutoTDelete<SkImageDecoder> decoder;
87 SkAutoTDelete<SkStreamRewindable> stream;
msarett95f192d2015-02-13 09:05:41 -080088 for (int i = 0; i < n; i++) {
scroggo60869a42015-04-01 12:09:17 -070089 // 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);
msarett95f192d2015-02-13 09:05:41 -080096 }
97}