1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Object.cpp: Defines the Object base class that provides
16// lifecycle support for GL objects using the traditional BindObject scheme, but
17// that need to be reference counted for correct cross-context deletion.
18
19#include "Object.hpp"
20
21#include "Common/Thread.hpp"
22
23namespace gl
24{
25#ifndef NDEBUG
26sw::MutexLock Object::instances_mutex;
27std::set<Object*> Object::instances;
28#endif
29
30Object::Object()
31{
32 referenceCount = 0;
33
34 #ifndef NDEBUG
35 LockGuard instances_lock(instances_mutex);
36 instances.insert(this);
37 #endif
38}
39
40Object::~Object()
41{
42 ASSERT(referenceCount == 0);
43
44 #ifndef NDEBUG
45 LockGuard instances_lock(instances_mutex);
46 ASSERT(instances.find(this) != instances.end()); // Check for double deletion
47 instances.erase(this);
48 #endif
49}
50
51void Object::addRef()
52{
53 sw::atomicIncrement(&referenceCount);
54}
55
56void Object::release()
57{
58 if(dereference() == 0)
59 {
60 delete this;
61 }
62}
63
64int Object::dereference()
65{
66 ASSERT(referenceCount > 0);
67
68 if(referenceCount > 0)
69 {
70 return sw::atomicDecrement(&referenceCount);
71 }
72
73 return 0;
74}
75
76void Object::destroy()
77{
78 referenceCount = 0;
79 delete this;
80}
81
82NamedObject::NamedObject(GLuint name) : name(name)
83{
84}
85
86NamedObject::~NamedObject()
87{
88}
89
90#ifndef NDEBUG
91struct ObjectLeakCheck
92{
93 ~ObjectLeakCheck()
94 {
95 LockGuard instances_lock(Object::instances_mutex);
96 ASSERT(Object::instances.empty()); // Check for GL object leak at termination
97 }
98};
99
100static ObjectLeakCheck objectLeakCheck;
101#endif
102
103}
104