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

#ifndef SkDrawable_DEFINED
#define SkDrawable_DEFINED

#include "include/core/SkFlattenable.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/private/SkAPI.h"

#include <cstddef>
#include <cstdint>
#include <memory>

class GrBackendDrawableInfo;
class SkCanvas;
class SkMatrix;
class SkPicture;
enum class GrBackendApi : unsigned int;
struct SkDeserialProcs;
struct SkIRect;
struct SkImageInfo;
struct SkRect;

/**
 *  Base-class for objects that draw into SkCanvas.
 *
 *  The object has a generation ID, which is guaranteed to be unique across all drawables. To
 *  allow for clients of the drawable that may want to cache the results, the drawable must
 *  change its generation ID whenever its internal state changes such that it will draw differently.
 */
class SK_API SkDrawable : public SkFlattenable {
public:
    /**
     *  Draws into the specified content. The drawing sequence will be balanced upon return
     *  (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
     *  and the current matrix and clip settings will not be changed.
     */
    void draw(SkCanvas*, const SkMatrix* = nullptr);
    void draw(SkCanvas*, SkScalar x, SkScalar y);

    /**
     *  When using the GPU backend it is possible for a drawable to execute using the underlying 3D
     *  API rather than the SkCanvas API. It does so by creating a GpuDrawHandler. The GPU backend
     *  is deferred so the handler will be given access to the 3D API at the correct point in the
     *  drawing stream as the GPU backend flushes. Since the drawable may mutate, each time it is
     *  drawn to a GPU-backed canvas a new handler is snapped, representing the drawable's state at
     *  the time of the snap.
     *
     *  When the GPU backend flushes to the 3D API it will call the draw method on the
     *  GpuDrawHandler. At this time the drawable may add commands to the stream of GPU commands for
     *  the unerlying 3D API. The draw function takes a GrBackendDrawableInfo which contains
     *  information about the current state of 3D API which the caller must respect. See
     *  GrBackendDrawableInfo for more specific details on what information is sent and the
     *  requirements for different 3D APIs.
     *
     *  Additionaly there may be a slight delay from when the drawable adds its commands to when
     *  those commands are actually submitted to the GPU. Thus the drawable or GpuDrawHandler is
     *  required to keep any resources that are used by its added commands alive and valid until
     *  those commands are submitted to the GPU. The GpuDrawHandler will be kept alive and then
     *  deleted once the commands are submitted to the GPU. The dtor of the GpuDrawHandler is the
     *  signal to the drawable that the commands have all been submitted. Different 3D APIs may have
     *  additional requirements for certain resources which require waiting for the GPU to finish
     *  all work on those resources before reusing or deleting them. In this case, the drawable can
     *  use the dtor call of the GpuDrawHandler to add a fence to the GPU to track when the GPU work
     *  has completed.
     *
     *  Currently this is only supported for the GPU Vulkan backend.
     */

    class GpuDrawHandler {
    public:
        virtual ~GpuDrawHandler() {}

        virtual void draw(const GrBackendDrawableInfo&) {}
    };

    /**
     * Snaps off a GpuDrawHandler to represent the state of the SkDrawable at the time the snap is
     * called. This is used for executing GPU backend specific draws intermixed with normal Skia GPU
     * draws. The GPU API, which will be used for the draw, as well as the full matrix, device clip
     * bounds and imageInfo of the target buffer are passed in as inputs.
     */
    std::unique_ptr<GpuDrawHandler> snapGpuDrawHandler(GrBackendApi backendApi,
                                                       const SkMatrix& matrix,
                                                       const SkIRect& clipBounds,
                                                       const SkImageInfo& bufferInfo) {
        return this->onSnapGpuDrawHandler(backendApi, matrix, clipBounds, bufferInfo);
    }

    /**
     * Returns an SkPicture with the contents of this SkDrawable.
     */
    sk_sp<SkPicture> makePictureSnapshot();

    /**
     *  Return a unique value for this instance. If two calls to this return the same value,
     *  it is presumed that calling the draw() method will render the same thing as well.
     *
     *  Subclasses that change their state should call notifyDrawingChanged() to ensure that
     *  a new value will be returned the next time it is called.
     */
    uint32_t getGenerationID();

    /**
     *  Return the (conservative) bounds of what the drawable will draw. If the drawable can
     *  change what it draws (e.g. animation or in response to some external change), then this
     *  must return a bounds that is always valid for all possible states.
     */
    SkRect getBounds();

    /**
     *  Return approximately how many bytes would be freed if this drawable is destroyed.
     *  The base implementation returns 0 to indicate that this is unknown.
     */
    size_t approximateBytesUsed();

    /**
     *  Calling this invalidates the previous generation ID, and causes a new one to be computed
     *  the next time getGenerationID() is called. Typically this is called by the object itself,
     *  in response to its internal state changing.
     */
    void notifyDrawingChanged();

    static SkFlattenable::Type GetFlattenableType() {
        return kSkDrawable_Type;
    }

    SkFlattenable::Type getFlattenableType() const override {
        return kSkDrawable_Type;
    }

    static sk_sp<SkDrawable> Deserialize(const void* data, size_t size,
                                          const SkDeserialProcs* procs = nullptr) {
        return sk_sp<SkDrawable>(static_cast<SkDrawable*>(
                                  SkFlattenable::Deserialize(
                                  kSkDrawable_Type, data, size, procs).release()));
    }

    Factory getFactory() const override { return nullptr; }
    const char* getTypeName() const override { return nullptr; }

protected:
    SkDrawable();

    virtual SkRect onGetBounds() = 0;
    virtual size_t onApproximateBytesUsed();
    virtual void onDraw(SkCanvas*) = 0;

    virtual std::unique_ptr<GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi, const SkMatrix&,
                                                                 const SkIRect& /*clipBounds*/,
                                                                 const SkImageInfo&) {
        return nullptr;
    }

    // TODO: Delete this once Android gets updated to take the clipBounds version above.
    virtual std::unique_ptr<GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi, const SkMatrix&) {
        return nullptr;
    }

    /**
     *  Default implementation calls onDraw() with a canvas that records into a picture. Subclasses
     *  may override if they have a more efficient way to return a picture for the current state
     *  of their drawable. Note: this picture must draw the same as what would be drawn from
     *  onDraw().
     */
    virtual sk_sp<SkPicture> onMakePictureSnapshot();

private:
    int32_t fGenerationID;
};

#endif
