1 /*
2 * Copyright (c) 2018-2021, 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 encode_buffer_allocator.cpp
24 //! \brief Defines the interface for buffer allocator
25 //! \details The allocator manages the buffers with the same type and alloc parameter
26 //!
27 #include "encode_tracked_buffer_queue.h"
28 #include <algorithm>
29 #include "encode_allocator.h"
30 #include "encode_utils.h"
31 #include "mos_os_hw.h"
32 #include "mos_os_specific.h"
33 #include "mos_utilities.h"
34
35 namespace encode {
36
BufferQueue(EncodeAllocator * allocator,MOS_ALLOC_GFXRES_PARAMS & param,uint32_t maxCount)37 BufferQueue::BufferQueue(EncodeAllocator *allocator, MOS_ALLOC_GFXRES_PARAMS ¶m, uint32_t maxCount)
38 : m_maxCount(maxCount),
39 m_allocator(allocator),
40 m_allocParam(param)
41 {
42 m_mutex = MosUtilities::MosCreateMutex();
43 }
44
~BufferQueue()45 BufferQueue::~BufferQueue()
46 {
47 for (auto resource : m_resources)
48 {
49 DestoryResource(resource);
50 }
51
52 MosUtilities::MosDestroyMutex(m_mutex);
53 }
54
AcquireResource()55 void *BufferQueue::AcquireResource()
56 {
57 AutoLock lock(m_mutex);
58
59 if (m_resourcePool.empty())
60 {
61 if (m_allocCount > m_maxCount)
62 {
63 ENCODE_VERBOSEMESSAGE("Reach max resource count, cannot allocate more");
64 return nullptr;
65 }
66
67 void *resource = AllocateResource();
68 if (resource != nullptr)
69 {
70 m_allocCount++;
71 m_resources.push_back(resource);
72 }
73 return resource;
74 }
75 else
76 {
77 void *resource = m_resourcePool.back();
78 m_resourcePool.pop_back();
79 return resource;
80 }
81 }
82
ReleaseResource(void * resource)83 MOS_STATUS BufferQueue::ReleaseResource(void *resource)
84 {
85 AutoLock lock(m_mutex);
86
87 if (nullptr != resource)
88 {
89 if (std::find(m_resources.begin(), m_resources.end(), resource) == m_resources.end())
90 {
91 // resource not belong to this allocator
92 ENCODE_VERBOSEMESSAGE("resource not belonged to current allocator");
93 return MOS_STATUS_INVALID_PARAMETER;
94 }
95 if (std::find(m_resourcePool.begin(), m_resourcePool.end(), resource) != m_resourcePool.end())
96 {
97 // resource already released
98 ENCODE_VERBOSEMESSAGE("resource already returned");
99 return MOS_STATUS_INVALID_PARAMETER;
100 }
101 m_resourcePool.push_back(resource);
102 }
103 return MOS_STATUS_SUCCESS;
104 }
105
SafeToDestory()106 bool BufferQueue::SafeToDestory()
107 {
108 AutoLock lock(m_mutex);
109
110 return m_resourcePool.size() == m_resources.size();
111 }
112
113
AllocateResource()114 void *BufferQueue::AllocateResource()
115 {
116 if (m_allocator)
117 {
118 if (m_resourceType == ResourceType::surfaceResource)
119 {
120 MOS_SURFACE* surface = nullptr;
121 surface = m_allocator->AllocateSurface(m_allocParam, false, MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE);
122 m_allocator->GetSurfaceInfo(surface);
123 return surface;
124 }
125 else if (m_resourceType == ResourceType::bufferResource)
126 {
127 return m_allocator->AllocateResource(m_allocParam, true);
128 }
129 else
130 {
131 return nullptr;
132 }
133
134 }
135 else
136 {
137 return nullptr;
138 }
139 }
140
DestoryResource(void * resource)141 MOS_STATUS BufferQueue::DestoryResource(void* resource)
142 {
143 if (nullptr != resource && nullptr != m_allocator)
144 {
145 if (m_resourceType == ResourceType::surfaceResource)
146 {
147 m_allocator->DestroySurface((MOS_SURFACE *)resource);
148 }
149 else if (m_resourceType == ResourceType::bufferResource)
150 {
151 m_allocator->DestroyResource((MOS_RESOURCE *)resource);
152 }
153 }
154 return MOS_STATUS_SUCCESS;
155 }
156
SetResourceType(ResourceType resType)157 void BufferQueue::SetResourceType(ResourceType resType)
158 {
159 m_resourceType = resType;
160 }
161
162 }