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

#ifndef GrFakeRefObj_DEFINED
#define GrFakeRefObj_DEFINED

#include "gl/GrGLInterface.h"
#include "GrNoncopyable.h"

////////////////////////////////////////////////////////////////////////////////
// This object is used to track the OpenGL objects. We don't use real
// reference counting (i.e., we don't free the objects when their ref count
// goes to 0) so that we can detect invalid memory accesses. The refs we
// are tracking in this class are actually OpenGL's references to the objects
// not "ours"
// Each object also gets a unique globally identifying ID
class GrFakeRefObj : public GrNoncopyable {
public:
    GrFakeRefObj()
        : fRef(0)
        , fHighRefCount(0)
        , fMarkedForDeletion(false)
        , fDeleted(false) {

        // source for globally unique IDs - 0 is reserved!
        static int fNextID = 0;

        fID = ++fNextID;
    }
    virtual ~GrFakeRefObj() {};

    void ref() {
        fRef++;
        if (fHighRefCount < fRef) {
            fHighRefCount = fRef;
        }
    }
    void unref() {
        fRef--;
        GrAlwaysAssert(fRef >= 0);

        // often in OpenGL a given object may still be in use when the
        // delete call is made. In these cases the object is marked
        // for deletion and then freed when it is no longer in use
        if (0 == fRef && fMarkedForDeletion) {
            this->deleteAction();
        }
    }
    int getRefCount() const             { return fRef; }
    int getHighRefCount() const         { return fHighRefCount; }

    GrGLuint getID() const              { return fID; }

    void setMarkedForDeletion()         { fMarkedForDeletion = true; }
    bool getMarkedForDeletion() const   { return fMarkedForDeletion; }

    bool getDeleted() const             { return fDeleted; }

    // The deleteAction fires if the object has been marked for deletion but
    // couldn't be deleted earlier due to refs
    virtual void deleteAction() {
        this->setDeleted();
    }

protected:
private:
    int         fRef;               // ref count
    int         fHighRefCount;      // high water mark of the ref count
    GrGLuint    fID;                // globally unique ID
    bool        fMarkedForDeletion;
    // The deleted flag is only set when OpenGL thinks the object is deleted
    // It is obviously still allocated w/in this framework
    bool        fDeleted;

    // setDeleted should only ever appear in the deleteAction method!
    void setDeleted()                   { fDeleted = true; }
};

////////////////////////////////////////////////////////////////////////////////
// Each class derived from GrFakeRefObj should use this macro to add a
// factory creation entry point. This entry point is used by the GrGLDebug
// object to instantiate the various objects
// all globally unique IDs
#define GR_DEFINE_CREATOR(className)                        \
    public:                                                 \
    static GrFakeRefObj *create ## className() {            \
        return SkNEW(className);                            \
    }

#endif // GrFakeRefObj_DEFINED
