1dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com/*
2dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com * Copyright 2012 Google Inc.
3dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com *
4dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
5dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com * found in the LICENSE file.
6dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com */
7dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
8dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#ifndef GrFakeRefObj_DEFINED
9dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#define GrFakeRefObj_DEFINED
10dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
11a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org#include "SkTypes.h"
12dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#include "gl/GrGLInterface.h"
13dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
14dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com////////////////////////////////////////////////////////////////////////////////
15dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// This object is used to track the OpenGL objects. We don't use real
16fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com// reference counting (i.e., we don't free the objects when their ref count
17dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// goes to 0) so that we can detect invalid memory accesses. The refs we
18dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// are tracking in this class are actually OpenGL's references to the objects
19dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// not "ours"
20dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// Each object also gets a unique globally identifying ID
21e3beb6bd7de7fa211681abbb0be58e80b19885e0commit-bot@chromium.orgclass GrFakeRefObj : SkNoncopyable {
22dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.compublic:
23fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    GrFakeRefObj()
24dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        : fRef(0)
25dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        , fMarkedForDeletion(false)
26dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        , fDeleted(false) {
27dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
280dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com        // source for globally unique IDs - 0 is reserved!
29fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        static int fNextID = 0;
30dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
31dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        fID = ++fNextID;
32dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    }
33dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    virtual ~GrFakeRefObj() {};
34dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
35fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    void ref() {
36fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        fRef++;
37dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    }
38fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    void unref() {
39fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        fRef--;
40dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        GrAlwaysAssert(fRef >= 0);
41dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
42fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        // often in OpenGL a given object may still be in use when the
43dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        // delete call is made. In these cases the object is marked
44dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        // for deletion and then freed when it is no longer in use
45dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        if (0 == fRef && fMarkedForDeletion) {
46fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com            this->deleteAction();
47dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        }
48dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    }
490dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    int getRefCount() const             { return fRef; }
50dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
510dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    GrGLuint getID() const              { return fID; }
52dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
530dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    void setMarkedForDeletion()         { fMarkedForDeletion = true; }
540dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    bool getMarkedForDeletion() const   { return fMarkedForDeletion; }
55dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
560dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    bool getDeleted() const             { return fDeleted; }
57dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
58dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    // The deleteAction fires if the object has been marked for deletion but
59dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    // couldn't be deleted earlier due to refs
60dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    virtual void deleteAction() {
61dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        this->setDeleted();
62dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    }
63dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
64dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.comprotected:
65dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.comprivate:
660dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    int         fRef;               // ref count
670dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    GrGLuint    fID;                // globally unique ID
68dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    bool        fMarkedForDeletion;
69dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    // The deleted flag is only set when OpenGL thinks the object is deleted
70dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    // It is obviously still allocated w/in this framework
71dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    bool        fDeleted;
72dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
73dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    // setDeleted should only ever appear in the deleteAction method!
740dd84a399ae8903784eac1c361c08449f822307frobertphillips@google.com    void setDeleted()                   { fDeleted = true; }
75dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com};
76dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
77dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com////////////////////////////////////////////////////////////////////////////////
78dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// Each class derived from GrFakeRefObj should use this macro to add a
79dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// factory creation entry point. This entry point is used by the GrGLDebug
80dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// object to instantiate the various objects
81dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com// all globally unique IDs
82dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#define GR_DEFINE_CREATOR(className)                        \
83dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    public:                                                 \
84dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    static GrFakeRefObj *create ## className() {            \
85dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com        return SkNEW(className);                            \
86dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com    }
87dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com
88dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#endif // GrFakeRefObj_DEFINED
89