
/*
 * 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 GrResourceCache2_DEFINED
#define GrResourceCache2_DEFINED

#include "GrGpuResource.h"
#include "GrGpuResourceCacheAccess.h"
#include "GrResourceKey.h"
#include "SkRefCnt.h"
#include "SkTInternalLList.h"
#include "SkTMultiMap.h"

/**
 * Manages the lifetime of all GrGpuResource instances.
 *
 * Resources may have optionally have two types of keys:
 *      1) A scratch key. This is for resources whose allocations are cached but not their contents.
 *         Multiple resources can share the same scratch key. This is so a caller can have two
 *         resource instances with the same properties (e.g. multipass rendering that ping-pongs
 *         between two temporary surfaces. The scratch key is set at resource creation time and
 *         should never change. Resources need not have a scratch key.
 *      2) A content key. This key represents the contents of the resource rather than just its
 *         allocation properties. They may not collide. The content key can be set after resource
 *         creation. Currently it may only be set once and cannot be cleared. This restriction will
 *         be removed.
 * If a resource has neither key type then it will be deleted as soon as the last reference to it
 * is dropped. If a key has both keys the content key takes precedence.
 */
class GrResourceCache2 {
public:
    GrResourceCache2();
    ~GrResourceCache2();

    /** Used to access functionality needed by GrGpuResource for lifetime management. */
    class ResourceAccess;
    ResourceAccess resourceAccess();

    /**
     * Sets the cache limits in terms of number of resources and max gpu memory byte size.
     */
    void setLimits(int count, size_t bytes);

    /**
     * Returns the number of resources.
     */
    int getResourceCount() const { return fCount; }

    /**
     * Returns the number of resources that count against the budget.
     */
    int getBudgetedResourceCount() const { return fBudgetedCount; }

    /**
     * Returns the number of bytes consumed by resources.
     */
    size_t getResourceBytes() const { return fBytes; }

    /**
     * Returns the number of bytes consumed by budgeted resources.
     */
    size_t getBudgetedResourceBytes() const { return fBudgetedBytes; }

    /**
     * Returns the cached resources count budget.
     */
    int getMaxResourceCount() const { return fMaxCount; }

    /**
     * Returns the number of bytes consumed by cached resources.
     */
    size_t getMaxResourceBytes() const { return fMaxBytes; }

    /**
     * Abandons the backend API resources owned by all GrGpuResource objects and removes them from
     * the cache.
     */
    void abandonAll();

    /**
     * Releases the backend API resources owned by all GrGpuResource objects and removes them from
     * the cache.
     */
    void releaseAll();

    enum {
        /** Preferentially returns scratch resources with no pending IO. */
        kPreferNoPendingIO_ScratchFlag = 0x1,
        /** Will not return any resources that match but have pending IO. */
        kRequireNoPendingIO_ScratchFlag = 0x2,
    };

    /**
     * Find a resource that matches a scratch key.
     */
    GrGpuResource* findAndRefScratchResource(const GrResourceKey& scratchKey, uint32_t flags = 0);
    
#ifdef SK_DEBUG
    // This is not particularly fast and only used for validation, so debug only.
    int countScratchEntriesForKey(const GrResourceKey& scratchKey) const {
        SkASSERT(scratchKey.isScratch());
        return fScratchMap.countForKey(scratchKey);
    }
#endif

    /**
     * Find a resource that matches a content key.
     */
    GrGpuResource* findAndRefContentResource(const GrResourceKey& contentKey) {
        SkASSERT(!contentKey.isScratch());
        GrGpuResource* resource = fContentHash.find(contentKey);
        if (resource) {
            resource->ref();
            this->makeResourceMRU(resource);
        }
        return resource;
    }

    /**
     * Query whether a content key exists in the cache.
     */
    bool hasContentKey(const GrResourceKey& contentKey) const {
        SkASSERT(!contentKey.isScratch());
        return SkToBool(fContentHash.find(contentKey));
    }

    /** Purges all resources that don't have external owners. */
    void purgeAllUnlocked();

    /**
     * The callback function used by the cache when it is still over budget after a purge. The
     * passed in 'data' is the same 'data' handed to setOverbudgetCallback.
     */
    typedef void (*PFOverBudgetCB)(void* data);

    /**
     * Set the callback the cache should use when it is still over budget after a purge. The 'data'
     * provided here will be passed back to the callback. Note that the cache will attempt to purge
     * any resources newly freed by the callback.
     */
    void setOverBudgetCallback(PFOverBudgetCB overBudgetCB, void* data) {
        fOverBudgetCB = overBudgetCB;
        fOverBudgetData = data;
    }

#if GR_GPU_STATS
    void printStats() const;
#endif

private:
    ///////////////////////////////////////////////////////////////////////////
    /// @name Methods accessible via ResourceAccess
    ////
    void insertResource(GrGpuResource*);
    void removeResource(GrGpuResource*);
    void notifyPurgable(GrGpuResource*);
    void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
    bool didSetContentKey(GrGpuResource*);
    void didChangeBudgetStatus(GrGpuResource*);
    void makeResourceMRU(GrGpuResource*);
    /// @}

    void purgeAsNeeded() {
        if (fPurging || (fBudgetedCount <= fMaxCount && fBudgetedBytes < fMaxBytes)) {
            return;
        }
        this->internalPurgeAsNeeded();
    }

    void internalPurgeAsNeeded();

#ifdef SK_DEBUG
    bool isInCache(const GrGpuResource* r) const { return fResources.isInList(r); }
    void validate() const;
#else
    void validate() const {}
#endif

    class AutoValidate;

    class AvailableForScratchUse;

    struct ScratchMapTraits {
        static const GrResourceKey& GetKey(const GrGpuResource& r) {
            return r.cacheAccess().getScratchKey();
        }

        static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
    };
    typedef SkTMultiMap<GrGpuResource, GrResourceKey, ScratchMapTraits> ScratchMap;

    struct ContentHashTraits {
        static const GrResourceKey& GetKey(const GrGpuResource& r) {
            return *r.cacheAccess().getContentKey();
        }

        static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); }
    };
    typedef SkTDynamicHash<GrGpuResource, GrResourceKey, ContentHashTraits> ContentHash;

    typedef SkTInternalLList<GrGpuResource> ResourceList;

    ResourceList                        fResources;
    // This map holds all resources that can be used as scratch resources.
    ScratchMap                          fScratchMap;
    // This holds all resources that have content keys.
    ContentHash                         fContentHash;

    // our budget, used in purgeAsNeeded()
    int                                 fMaxCount;
    size_t                              fMaxBytes;

#if GR_CACHE_STATS
    int                                 fHighWaterCount;
    size_t                              fHighWaterBytes;
    int                                 fBudgetedHighWaterCount;
    size_t                              fBudgetedHighWaterBytes;
#endif

    // our current stats for all resources
    int                                 fCount;
    size_t                              fBytes;

    // our current stats for resources that count against the budget
    int                                 fBudgetedCount;
    size_t                              fBudgetedBytes;

    // prevents recursive purging
    bool                                fPurging;
    bool                                fNewlyPurgableResourceWhilePurging;

    PFOverBudgetCB                      fOverBudgetCB;
    void*                               fOverBudgetData;

};

class GrResourceCache2::ResourceAccess {
private:
    ResourceAccess(GrResourceCache2* cache) : fCache(cache) { }
    ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { }
    ResourceAccess& operator=(const ResourceAccess&); // unimpl

    /**
     * Insert a resource into the cache.
     */
    void insertResource(GrGpuResource* resource) { fCache->insertResource(resource); }

    /**
     * Removes a resource from the cache.
     */
    void removeResource(GrGpuResource* resource) { fCache->removeResource(resource); }

    /**
     * Called by GrGpuResources when they detects that they are newly purgable.
     */
    void notifyPurgable(GrGpuResource* resource) { fCache->notifyPurgable(resource); }

    /**
     * Called by GrGpuResources when their sizes change.
     */
    void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) {
        fCache->didChangeGpuMemorySize(resource, oldSize);
    }

    /**
     * Called by GrGpuResources when their content keys change.
     *
     * This currently returns a bool and fails when an existing resource has a key that collides
     * with the new content key. In the future it will null out the content key for the existing
     * resource. The failure is a temporary measure taken because duties are split between two
     * cache objects currently.
     */
    bool didSetContentKey(GrGpuResource* resource) { return fCache->didSetContentKey(resource); }


    /**
     * Called by GrGpuResources when they change from budgeted to unbudgeted or vice versa.
     */
    void didChangeBudgetStatus(GrGpuResource* resource) { fCache->didChangeBudgetStatus(resource); }

    // No taking addresses of this type.
    const ResourceAccess* operator&() const;
    ResourceAccess* operator&();

    GrResourceCache2* fCache;

    friend class GrGpuResource; // To access all the proxy inline methods.
    friend class GrResourceCache2; // To create this type.
};

inline GrResourceCache2::ResourceAccess GrResourceCache2::resourceAccess() {
    return ResourceAccess(this);
}

#endif
