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

#ifndef GrDeferredUpload_DEFINED
#define GrDeferredUpload_DEFINED

#include <functional>
#include "GrTypes.h"

class GrTextureProxy;

/**
 * A word about deferred uploads and tokens: Ops should usually schedule their uploads to occur at
 * the beginning of a frame whenever possible. These are called ASAP uploads. Of course, this
 * requires that there are no draws that have yet to be flushed that rely on the old texture
 * contents. In that case the ASAP upload would happen prior to the draw and therefore the draw
 * would read the new (wrong) texture data. When this read-before-write data hazard exists they
 * should schedule an inline upload.
 *
 * Ops, in conjunction with helpers such as GrDrawOpAtlas, use upload tokens to know what the most
 * recent draw was that referenced a resource (or portion of a resource). Each draw is assigned a
 * token. A resource (or portion thereof) can be tagged with the most recent reading draw's token.
 * The deferred uploads target provides a facility for testing whether the draw corresponding to the
 * token has been flushed. If it has not been flushed then the op must perform an inline upload
 * instead so that the upload occurs after the draw depending on the old contents and before the
 * draw depending on the updated contents. When scheduling an inline upload the op provides the
 * token of the draw that the upload must occur before.
 */

/**
 * GrDeferredUploadToken is used to sequence the uploads relative to each other and to draws.
 */
class GrDeferredUploadToken {
public:
    static GrDeferredUploadToken AlreadyFlushedToken() { return GrDeferredUploadToken(0); }

    GrDeferredUploadToken(const GrDeferredUploadToken&) = default;
    GrDeferredUploadToken& operator=(const GrDeferredUploadToken&) = default;

    bool operator==(const GrDeferredUploadToken& that) const {
        return fSequenceNumber == that.fSequenceNumber;
    }
    bool operator!=(const GrDeferredUploadToken& that) const { return !(*this == that); }
    bool operator<(const GrDeferredUploadToken that) const {
        return fSequenceNumber < that.fSequenceNumber;
    }
    bool operator<=(const GrDeferredUploadToken that) const {
        return fSequenceNumber <= that.fSequenceNumber;
    }
    bool operator>(const GrDeferredUploadToken that) const {
        return fSequenceNumber > that.fSequenceNumber;
    }
    bool operator>=(const GrDeferredUploadToken that) const {
        return fSequenceNumber >= that.fSequenceNumber;
    }

    GrDeferredUploadToken& operator++() {
        ++fSequenceNumber;
        return *this;
    }
    GrDeferredUploadToken operator++(int) {
        auto old = fSequenceNumber;
        ++fSequenceNumber;
        return GrDeferredUploadToken(old);
    }

    GrDeferredUploadToken next() const { return GrDeferredUploadToken(fSequenceNumber + 1); }

    /** Is this token in the [start, end] inclusive interval? */
    bool inInterval(const GrDeferredUploadToken& start, const GrDeferredUploadToken& end) {
        return *this >= start && *this <= end;
    }

private:
    GrDeferredUploadToken() = delete;
    explicit GrDeferredUploadToken(uint64_t sequenceNumber) : fSequenceNumber(sequenceNumber) {}
    uint64_t fSequenceNumber;
};

/*
 * The GrTokenTracker encapsulates the incrementing and distribution of tokens.
 */
class GrTokenTracker {
public:
    /** Gets the token one beyond the last token that has been flushed. */
    GrDeferredUploadToken nextTokenToFlush() const { return fLastFlushedToken.next(); }

    /** Gets the next draw token that will be issued by this target. This can be used by an op
        to record that the next draw it issues will use a resource (e.g. texture) while preparing
        that draw. */
    GrDeferredUploadToken nextDrawToken() const { return fLastIssuedToken.next(); }

private:
    // Only these two classes get to increment the token counters
    friend class SkInternalAtlasTextContext;
    friend class GrOpFlushState;

    /** Issues the next token for a draw. */
    GrDeferredUploadToken issueDrawToken() { return ++fLastIssuedToken; }

    /** Advances the last flushed token by one. */
    GrDeferredUploadToken flushToken() { return ++fLastFlushedToken; }

    GrDeferredUploadToken fLastIssuedToken = GrDeferredUploadToken::AlreadyFlushedToken();
    GrDeferredUploadToken fLastFlushedToken = GrDeferredUploadToken::AlreadyFlushedToken();
};

/**
 * Passed to a deferred upload when it is executed, this method allows the deferred upload to
 * actually write its pixel data into a texture.
 */
using GrDeferredTextureUploadWritePixelsFn =
        std::function<bool(GrTextureProxy*, int left, int top, int width, int height,
                           GrPixelConfig config, const void* buffer, size_t rowBytes)>;

/**
 * A deferred texture upload is simply a std::function that takes a
 * GrDeferredTextureUploadWritePixelsFn as a parameter. It is called when it should perform its
 * upload as the draw/upload sequence is executed.
 */
using GrDeferredTextureUploadFn = std::function<void(GrDeferredTextureUploadWritePixelsFn&)>;

/**
 * An interface for scheduling deferred uploads. It accepts asap and deferred inline uploads.
 */
class GrDeferredUploadTarget {
public:
    virtual ~GrDeferredUploadTarget() {}

    virtual const GrTokenTracker* tokenTracker() = 0;

    /** Returns the token of the draw that this upload will occur before. */
    virtual GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) = 0;

    /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
        are done first during a flush, this will be the first token since the most recent
        flush. */
    virtual GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&& upload) = 0;
};

#endif
