xref: /aosp_15_r20/external/intel-media-driver/media_common/agnostic/common/heap_manager/frame_tracker.h (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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     frame_tracker.h
24 //! \brief    Manages the multiple trackers in one place.
25 //!
26 
27 #ifndef __FRAME_TRACKER_H__
28 #define __FRAME_TRACKER_H__
29 
30 #include "mos_os.h"
31 #include <map>
32 
33 #define MAX_TRACKER_NUMBER 64
34 #define CHK_INDEX(index) if ((index) >= MAX_TRACKER_NUMBER) {return MOS_STATUS_NOT_ENOUGH_BUFFER; }
35 
36 class FrameTrackerToken;
37 class FrameTrackerProducer;
38 
39 // C-style struct for FrameTrackerToken
40 // for tokens that embeded in a struct other than a class
41 // in legacy DSH code, the token is always embeded in another struct
42 struct FrameTrackerTokenFlat
43 {
44     FrameTrackerProducer *producer;
45     uint32_t trackers[MAX_TRACKER_NUMBER];
46     bool valid;
47     bool stick;
48 };
49 
50 bool FrameTrackerTokenFlat_IsExpired(const FrameTrackerTokenFlat *self);
51 
FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat * self,uint32_t index,uint32_t tracker)52 static inline void FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat *self, uint32_t index, uint32_t tracker)
53 {
54     if (index < MAX_TRACKER_NUMBER && tracker != 0)
55     {
56         self->trackers[index] = tracker;
57     }
58 }
59 
FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat * self,const FrameTrackerTokenFlat * token)60 static inline void FrameTrackerTokenFlat_Merge(FrameTrackerTokenFlat *self, const FrameTrackerTokenFlat *token)
61 {
62     self->producer = token->producer;
63     for (int i = 0; i < MAX_TRACKER_NUMBER; i++)
64     {
65         if (token->trackers[i] != 0)
66         {
67             FrameTrackerTokenFlat_Merge(self, i, token->trackers[i]);
68         }
69     }
70 }
71 
FrameTrackerTokenFlat_SetProducer(FrameTrackerTokenFlat * self,FrameTrackerProducer * producer)72 static inline void FrameTrackerTokenFlat_SetProducer(FrameTrackerTokenFlat *self, FrameTrackerProducer *producer)
73 {
74     self->producer = producer;
75 }
76 
FrameTrackerTokenFlat_Clear(FrameTrackerTokenFlat * self)77 static inline void FrameTrackerTokenFlat_Clear(FrameTrackerTokenFlat *self)
78 {
79     self->stick = false;
80     MOS_ZeroMemory(self->trackers, sizeof(self->trackers));
81 }
82 
FrameTrackerTokenFlat_Validate(FrameTrackerTokenFlat * self)83 static inline void FrameTrackerTokenFlat_Validate(FrameTrackerTokenFlat *self)
84 {
85     self->valid = true;
86 }
87 
FrameTrackerTokenFlat_Invalidate(FrameTrackerTokenFlat * self)88 static inline void FrameTrackerTokenFlat_Invalidate(FrameTrackerTokenFlat *self)
89 {
90     self->valid = false;
91 }
92 
FrameTrackerTokenFlat_IsValid(const FrameTrackerTokenFlat * self)93 static inline bool FrameTrackerTokenFlat_IsValid(const FrameTrackerTokenFlat *self)
94 {
95     return self->valid;
96 }
97 
FrameTrackerTokenFlat_Stick(FrameTrackerTokenFlat * self)98 static inline void FrameTrackerTokenFlat_Stick(FrameTrackerTokenFlat *self)
99 {
100     self->stick = true;
101 }
102 
103 class FrameTrackerProducer
104 {
105 public:
106     FrameTrackerProducer();
107     ~FrameTrackerProducer();
108 
109     MOS_STATUS Initialize(MOS_INTERFACE *osInterface);
110 
111     int AssignNewTracker();
112 
GetLatestTrackerResource(uint32_t index,MOS_RESOURCE ** resource,uint32_t * offset)113     inline void GetLatestTrackerResource(uint32_t index, MOS_RESOURCE **resource, uint32_t *offset)
114     {
115         *resource = &m_resource;
116         *offset = index * m_trackerSize;
117     }
118 
GetLatestTrackerAddress(uint32_t index)119     inline volatile uint32_t *GetLatestTrackerAddress(uint32_t index)
120     {
121         return (uint32_t *)((uint8_t *)m_resourceData + index * m_trackerSize);
122     }
123 
GetNextTracker(uint32_t index)124     inline uint32_t GetNextTracker(uint32_t index) { return m_counters[index];}
125 
StepForward(uint32_t index)126     inline MOS_STATUS StepForward(uint32_t index)
127     {
128         CHK_INDEX(index);
129         ++ m_counters[index];
130         if (m_counters[index] == 0)
131         {
132             m_counters[index] = 1;
133         }
134         return MOS_STATUS_SUCCESS;
135     }
136 
137 protected:
138     // indexes to assign a new tracer
139     uint32_t m_nextTrackerIndex;
140     bool m_trackerInUse[MAX_TRACKER_NUMBER];
141 
142     // resource
143     static const uint32_t m_trackerSize = 8; // reserved two dwords for each tracker
144     MOS_RESOURCE m_resource;
145     uint32_t *m_resourceData;
146 
147     // counters
148     uint32_t m_counters[MAX_TRACKER_NUMBER];
149 
150     // interfaces
151     MOS_INTERFACE *m_osInterface;
152 };
153 
154 class FrameTrackerToken
155 {
156 public:
FrameTrackerToken()157     FrameTrackerToken():
158         m_producer(nullptr)
159     {
160     }
161 
~FrameTrackerToken()162     ~FrameTrackerToken()
163     {
164     }
165 
IsExpired()166     bool IsExpired()
167     {
168         if (m_producer == nullptr)
169         {
170             return true;
171         }
172 
173         for (auto ite = m_holdTrackers.begin(); ite != m_holdTrackers.end(); ite ++)
174         {
175             uint32_t index = ite->first;
176             volatile uint32_t latestTracker = *(m_producer->GetLatestTrackerAddress(index));
177             uint32_t holdTracker = ite->second;
178             if ((int)(holdTracker - latestTracker) > 0)
179             {
180                 return false;
181             }
182         }
183         return true;
184     }
185 
186     void Merge(const FrameTrackerToken *token);
187 
Merge(uint32_t index,uint32_t tracker)188     inline void Merge(uint32_t index, uint32_t tracker) {m_holdTrackers[index] = tracker; }
189 
SetProducer(FrameTrackerProducer * producer)190     inline void SetProducer(FrameTrackerProducer *producer)
191     {
192         m_producer = producer;
193     }
194 
Clear()195     inline void Clear() {m_holdTrackers.clear(); }
196 
197 protected:
198     FrameTrackerProducer *m_producer;
199     std::map<uint32_t, uint32_t> m_holdTrackers;
200 };
201 
202 #endif // __FRAME_TRACKER_H__
203