1 /*
2 * Copyright (c) 2019, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     decode_resource_array.h
24 //! \brief    Defines the interface for surface array
25 //! \details  The surface array record the index for picking up surface,
26 //!           can be used as recycle surfaces.
27 //!
28 
29 #ifndef __DECODE_RESOURCE_ARRAY_H__
30 #define __DECODE_RESOURCE_ARRAY_H__
31 #include <map>
32 #include <vector>
33 #include "mos_os.h"
34 #include "decode_allocator.h"
35 #include "decode_utils.h"
36 
37 namespace decode
38 {
39 
40 template <class T>
41 class ResourceArray
42 {
43 public:
44     //!
45     //! \brief  Constructor
46     //!
ResourceArray(DecodeAllocator * allocator)47     ResourceArray(DecodeAllocator *allocator)
48         : m_allocator(allocator)
49     {}
50 
51     //!
52     //! \brief  Constructor
53     //!
ResourceArray()54     ResourceArray()
55     {}
56 
57     //!
58     //! \brief  Destructor
59     //!
~ResourceArray()60     virtual ~ResourceArray() { Destroy(); }
61 
62     //!
63     //! \brief  Add one resource to resource queue
64     //! \param  [in] resource
65     //!         point of resource
66     //! \param  [in] size
67     //!         size of resource
68     //! \return No return
69     //!
Push(T * resource)70     void Push(T *resource)
71     {
72         if (resource != nullptr)
73         {
74             m_resourceQueue.push_back(resource);
75         }
76     }
77 
78     //!
79     //! \brief  Get number of surface array
80     //! \return uint32_t
81     //!         Return the number of surface array
82     //!
ArraySize()83     uint32_t ArraySize()
84     {
85         return m_resourceQueue.size();
86     }
87 
88     //!
89     //! \brief  Get next resource from resource queue, loop back to first element if reach end
90     //! \return T* &
91     //!         point of resource if success, else nullptr if the array is empty
92     //!
Fetch()93     T* & Fetch()
94     {
95         if (m_resourceQueue.empty())
96         {
97             return m_empty;
98         }
99 
100         m_nextIndex++;
101         if (m_nextIndex >= m_resourceQueue.size())
102         {
103             m_nextIndex = 0;
104         }
105 
106         return m_resourceQueue[m_nextIndex];
107     }
108 
109     //!
110     //! \brief  Get current resource from resource queue
111     //! \return T*
112     //!         point of resource if success, else nullptr if the array is empty
113     //!
Peek()114     T* Peek()
115     {
116         if (m_resourceQueue.empty())
117         {
118             return m_empty;
119         }
120 
121         return m_resourceQueue[m_nextIndex];
122     }
123 
124     //!
125     //! \brief  Get surface from surface queue by index
126     //! \param  [in] index
127     //!         resource index
128     //! \return T*
129     //!         Point to resource
130     //!
131     T* & operator[] (uint32_t index)
132     {
133         if (m_resourceQueue.empty())
134         {
135             return m_empty;
136         }
137 
138         if (index >= m_resourceQueue.size())
139         {
140             return m_empty;
141         }
142 
143         return m_resourceQueue[index];
144     }
145 
146 private:
147     //!
148     //! \brief  Destroy resource array
149     //! \return MOS_STATUS
150     //!         MOS_STATUS_SUCCESS if success, else fail reason
151     //!
Destroy()152     MOS_STATUS Destroy()
153     {
154         for (auto &resource : m_resourceQueue)
155         {
156             if (resource == nullptr)
157             {
158                 continue;
159             }
160             if (m_allocator != nullptr)
161             {
162                 DECODE_CHK_STATUS(m_allocator->Destroy(resource));
163             }
164         }
165 
166         m_resourceQueue.clear();
167 
168         return MOS_STATUS_SUCCESS;
169     }
170 
171 private:
172     DecodeAllocator *m_allocator = nullptr;
173 
174     std::vector<T *> m_resourceQueue; //!< resource queue
175     uint32_t m_nextIndex  = 0;
176 
177     T* m_empty = nullptr;
178 
179 MEDIA_CLASS_DEFINE_END(decode__ResourceArray)
180 };
181 
182 }  // namespace decode
183 #endif  // !__DECODE_SURFACE_ARRAY_H__
184