1 // Copyright 2018 The Dawn Authors 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 #ifndef DAWNNATIVE_OBJECTBASE_H_ 16 #define DAWNNATIVE_OBJECTBASE_H_ 17 18 #include "common/LinkedList.h" 19 #include "common/RefCounted.h" 20 #include "dawn_native/Forward.h" 21 22 #include <string> 23 24 namespace dawn_native { 25 26 class DeviceBase; 27 28 class ObjectBase : public RefCounted { 29 public: 30 struct ErrorTag {}; 31 static constexpr ErrorTag kError = {}; 32 33 explicit ObjectBase(DeviceBase* device); 34 ObjectBase(DeviceBase* device, ErrorTag tag); 35 36 DeviceBase* GetDevice() const; 37 bool IsError() const; 38 39 private: 40 // Pointer to owning device. 41 DeviceBase* mDevice; 42 }; 43 44 class ApiObjectBase : public ObjectBase, public LinkNode<ApiObjectBase> { 45 public: 46 struct LabelNotImplementedTag {}; 47 static constexpr LabelNotImplementedTag kLabelNotImplemented = {}; 48 struct UntrackedByDeviceTag {}; 49 static constexpr UntrackedByDeviceTag kUntrackedByDevice = {}; 50 51 ApiObjectBase(DeviceBase* device, LabelNotImplementedTag tag); 52 ApiObjectBase(DeviceBase* device, const char* label); 53 ApiObjectBase(DeviceBase* device, ErrorTag tag); 54 ~ApiObjectBase() override; 55 56 virtual ObjectType GetType() const = 0; 57 const std::string& GetLabel() const; 58 59 // The ApiObjectBase is considered alive if it is tracked in a respective linked list owned 60 // by the owning device. 61 bool IsAlive() const; 62 63 // This needs to be public because it can be called from the device owning the object. 64 void Destroy(); 65 66 // Dawn API 67 void APISetLabel(const char* label); 68 69 protected: 70 // Overriding of the RefCounted's DeleteThis function ensures that instances of objects 71 // always call their derived class implementation of Destroy prior to the derived 72 // class being destroyed. This guarantees that when ApiObjects' reference counts drop to 0, 73 // then the underlying backend's Destroy calls are executed. We cannot naively put the call 74 // to Destroy in the destructor of this class because it calls DestroyImpl 75 // which is a virtual function often implemented in the Derived class which would already 76 // have been destroyed by the time ApiObject's destructor is called by C++'s destruction 77 // order. Note that some classes like BindGroup may override the DeleteThis function again, 78 // and they should ensure that their overriding versions call this underlying version 79 // somewhere. 80 void DeleteThis() override; 81 void TrackInDevice(); 82 83 // Sub-classes may override this function multiple times. Whenever overriding this function, 84 // however, users should be sure to call their parent's version in the new override to make 85 // sure that all destroy functionality is kept. This function is guaranteed to only be 86 // called once through the exposed Destroy function. 87 virtual void DestroyImpl() = 0; 88 89 private: 90 virtual void SetLabelImpl(); 91 92 std::string mLabel; 93 }; 94 95 } // namespace dawn_native 96 97 #endif // DAWNNATIVE_OBJECTBASE_H_ 98