/*
 * 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/base/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
