/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkBitmap.h"
#include "SkData.h"
#include "SkForceLinking.h"
#include "SkImageDecoder.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkString.h"

__SK_FORCE_IMAGE_DECODER_LINKING;

class SkCanvas;

class SkipZeroesBench : public SkBenchmark {
public:
    SkipZeroesBench(const char* filename, bool skipZeroes)
    : fName("SkipZeroes_")
    , fDecoder(NULL)
    , fFilename(filename)
    , fStream()
    , fSkipZeroes(skipZeroes)
    , fValid(false) {
        fName.append(filename);
        if (skipZeroes) {
            fName.append("_skip_zeroes");
        } else {
            fName.append("_write_zeroes");
        }
    }

    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
        return backend == kNonRendering_Backend;
    }

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onPreDraw() SK_OVERRIDE {
        const char* resPath = GetResourcePath().c_str();
        if (NULL == resPath) {
            fValid = false;
            return;
        }

        SkString fullPath = SkOSPath::SkPathJoin(resPath, fFilename.c_str());
        SkFILEStream fileStream(fullPath.c_str());
        fValid = fileStream.isValid() && fileStream.getLength() > 0;
        if (fValid) {
            const size_t size = fileStream.getLength();
            void* data = sk_malloc_throw(size);
            if (fileStream.read(data, size) < size) {
                fValid = false;
            } else {
                SkAutoTUnref<SkData> skdata(SkData::NewFromMalloc(data, size));
                fStream.setData(skdata.get());
                fDecoder.reset(SkImageDecoder::Factory(&fStream));
                if (fDecoder.get()) {
                    fDecoder->setSkipWritingZeroes(fSkipZeroes);
                } else {
                    fValid = false;
                }
            }
        }
    }

    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        if (!fValid) {
#ifdef SK_DEBUG
            SkDebugf("stream was invalid: %s\n", fFilename.c_str());
#endif
            return;
        }
        // Decode a bunch of times
        SkBitmap bm;
        for (int i = 0; i < loops; ++i) {
            SkDEBUGCODE(bool success =) fDecoder->decode(&fStream, &bm,
                                                         SkImageDecoder::kDecodePixels_Mode);
#ifdef SK_DEBUG
            if (!success) {
                SkDebugf("failed to decode %s\n", fFilename.c_str());
                return;
            }
#endif
            SkDEBUGCODE(success =) fStream.rewind();
#ifdef SK_DEBUG
            if (!success) {
                SkDebugf("failed to rewind %s\n", fFilename.c_str());
                return;
            }
#endif
        }
    }

private:
    SkString                        fName;
    SkAutoTDelete<SkImageDecoder>   fDecoder;
    const SkString                  fFilename;
    SkMemoryStream                  fStream;
    bool                            fSkipZeroes;
    bool                            fValid;

    typedef SkBenchmark INHERITED;
};

// Enable the true version once the feature is checked in.
DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", true)));
DEF_BENCH( return SkNEW_ARGS(SkipZeroesBench, ("arrow.png", false)));
