1111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com/*
2111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com * Copyright 2013 Google Inc.
3111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com *
4111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com * Use of this source code is governed by a BSD-style license that can be
5111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com * found in the LICENSE file.
6111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com */
7111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
9bcbc1788b478b1e54079318ad073e8490aa66faetfarina#include "Resources.h"
10111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkBitmap.h"
11111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkData.h"
12111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkForceLinking.h"
13111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkImageDecoder.h"
14111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkOSFile.h"
15111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkStream.h"
16111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#include "SkString.h"
17111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
18111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com__SK_FORCE_IMAGE_DECODER_LINKING;
19111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
20111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.comclass SkCanvas;
21111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
22f168b86d7fafc5c20c87bebc6fd393cb17e120catfarinaclass SkipZeroesBench : public Benchmark {
23111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.compublic:
24111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    SkipZeroesBench(const char* filename, bool skipZeroes)
25111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    : fName("SkipZeroes_")
26111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    , fDecoder(NULL)
27111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    , fFilename(filename)
28111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    , fStream()
29111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    , fSkipZeroes(skipZeroes)
30111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    , fValid(false) {
31111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        fName.append(filename);
32111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        if (skipZeroes) {
33111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            fName.append("_skip_zeroes");
34111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        } else {
35111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            fName.append("_write_zeroes");
36111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        }
37644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    }
38644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org
39644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
40644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        return backend == kNonRendering_Backend;
41111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
42111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
43111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.comprotected:
44111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    virtual const char* onGetName() SK_OVERRIDE {
45111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        return fName.c_str();
46111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
47111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
48111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    virtual void onPreDraw() SK_OVERRIDE {
49880914c35c8f7fc2e9c57134134c883baf66e538tfarina        SkString resourcePath = GetResourcePath();
50880914c35c8f7fc2e9c57134134c883baf66e538tfarina        if (resourcePath.isEmpty()) {
51111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            fValid = false;
52111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            return;
53111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        }
54111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
55880914c35c8f7fc2e9c57134134c883baf66e538tfarina        SkString fullPath = SkOSPath::SkPathJoin(resourcePath.c_str(),
56880914c35c8f7fc2e9c57134134c883baf66e538tfarina                                                 fFilename.c_str());
57111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        SkFILEStream fileStream(fullPath.c_str());
58111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        fValid = fileStream.isValid() && fileStream.getLength() > 0;
59111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        if (fValid) {
60111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            const size_t size = fileStream.getLength();
61111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            void* data = sk_malloc_throw(size);
62111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            if (fileStream.read(data, size) < size) {
63111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                fValid = false;
64111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            } else {
65111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                SkAutoTUnref<SkData> skdata(SkData::NewFromMalloc(data, size));
66111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                fStream.setData(skdata.get());
67111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                fDecoder.reset(SkImageDecoder::Factory(&fStream));
68111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                if (fDecoder.get()) {
698d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.com                    fDecoder->setSkipWritingZeroes(fSkipZeroes);
70111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                } else {
71111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                    fValid = false;
72111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                }
73111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            }
74111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        }
75111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
76111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
773361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
78111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        if (!fValid) {
79111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#ifdef SK_DEBUG
80111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            SkDebugf("stream was invalid: %s\n", fFilename.c_str());
81111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#endif
82111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            return;
83111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        }
84111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        // Decode a bunch of times
85111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        SkBitmap bm;
863361471a3504ecd0351ff70f4c42d8d6fee963d4commit-bot@chromium.org        for (int i = 0; i < loops; ++i) {
87111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            SkDEBUGCODE(bool success =) fDecoder->decode(&fStream, &bm,
88111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                                                         SkImageDecoder::kDecodePixels_Mode);
89111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#ifdef SK_DEBUG
90111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            if (!success) {
91111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                SkDebugf("failed to decode %s\n", fFilename.c_str());
92111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                return;
93111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            }
94111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#endif
95111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            SkDEBUGCODE(success =) fStream.rewind();
96111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#ifdef SK_DEBUG
97111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            if (!success) {
98111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                SkDebugf("failed to rewind %s\n", fFilename.c_str());
99111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com                return;
100111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com            }
101111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com#endif
102111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        }
103111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
104111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
105111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.comprivate:
106111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    SkString                        fName;
107111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    SkAutoTDelete<SkImageDecoder>   fDecoder;
108111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    const SkString                  fFilename;
109111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    SkMemoryStream                  fStream;
110111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    bool                            fSkipZeroes;
111111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    bool                            fValid;
112111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
113f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    typedef Benchmark INHERITED;
114111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com};
115111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
116111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com// Enable the true version once the feature is checked in.
1178d2392487cd97e68c0a71da9fd5d2b42ecac5ec8scroggo@google.comDEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", true)));
118111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.comDEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", false)));
119