xref: /aosp_15_r20/external/angle/src/libANGLE/CLEvent.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLEvent.cpp: Implements the cl::Event class.
7 
8 #include "libANGLE/CLEvent.h"
9 
10 #include "libANGLE/CLCommandQueue.h"
11 #include "libANGLE/CLContext.h"
12 #include "libANGLE/cl_utils.h"
13 
14 #include <cstring>
15 
16 namespace cl
17 {
18 
setUserEventStatus(cl_int executionStatus)19 angle::Result Event::setUserEventStatus(cl_int executionStatus)
20 {
21     ANGLE_TRY(mImpl->setUserEventStatus(executionStatus));
22     mStatusWasChanged = true;
23     return angle::Result::Continue;
24 }
25 
getInfo(EventInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const26 angle::Result Event::getInfo(EventInfo name,
27                              size_t valueSize,
28                              void *value,
29                              size_t *valueSizeRet) const
30 {
31     cl_int execStatus     = 0;
32     cl_uint valUInt       = 0u;
33     void *valPointer      = nullptr;
34     const void *copyValue = nullptr;
35     size_t copySize       = 0u;
36 
37     switch (name)
38     {
39         case EventInfo::CommandQueue:
40             valPointer = CommandQueue::CastNative(mCommandQueue.get());
41             copyValue  = &valPointer;
42             copySize   = sizeof(valPointer);
43             break;
44         case EventInfo::CommandType:
45             copyValue = &mCommandType;
46             copySize  = sizeof(mCommandType);
47             break;
48         case EventInfo::ReferenceCount:
49             valUInt   = getRefCount();
50             copyValue = &valUInt;
51             copySize  = sizeof(valUInt);
52             break;
53         case EventInfo::CommandExecutionStatus:
54         {
55             ANGLE_TRY(mImpl->getCommandExecutionStatus(execStatus));
56             copyValue = &execStatus;
57             copySize  = sizeof(execStatus);
58             break;
59         }
60         case EventInfo::Context:
61             valPointer = mContext->getNative();
62             copyValue  = &valPointer;
63             copySize   = sizeof(valPointer);
64             break;
65         default:
66             ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
67     }
68 
69     if (value != nullptr)
70     {
71         // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
72         // as described in the Event Queries table and param_value is not NULL.
73         if (valueSize < copySize)
74         {
75             ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
76         }
77         if (copyValue != nullptr)
78         {
79             std::memcpy(value, copyValue, copySize);
80         }
81     }
82     if (valueSizeRet != nullptr)
83     {
84         *valueSizeRet = copySize;
85     }
86     return angle::Result::Continue;
87 }
88 
setCallback(cl_int commandExecCallbackType,EventCB pfnNotify,void * userData)89 angle::Result Event::setCallback(cl_int commandExecCallbackType, EventCB pfnNotify, void *userData)
90 {
91     auto callbacks = mCallbacks.synchronize();
92 
93     // Spec mentions that the callback will be called when the execution status of the event is
94     // equal to past the status specified by commandExecCallbackType
95     cl_int currentStatus;
96     ANGLE_TRY(mImpl->getCommandExecutionStatus(currentStatus));
97     if (currentStatus <= commandExecCallbackType)
98     {
99         pfnNotify(this, commandExecCallbackType, userData);
100         return angle::Result::Continue;
101     }
102 
103     // Only when required register a single callback with the back end for each callback type.
104     if ((*callbacks)[commandExecCallbackType].empty())
105     {
106         ANGLE_TRY(mImpl->setCallback(*this, commandExecCallbackType));
107         // This event has to be retained until the callback is called.
108         retain();
109     }
110     (*callbacks)[commandExecCallbackType].emplace_back(pfnNotify, userData);
111     return angle::Result::Continue;
112 }
113 
getProfilingInfo(ProfilingInfo name,size_t valueSize,void * value,size_t * valueSizeRet)114 angle::Result Event::getProfilingInfo(ProfilingInfo name,
115                                       size_t valueSize,
116                                       void *value,
117                                       size_t *valueSizeRet)
118 {
119     return mImpl->getProfilingInfo(name, valueSize, value, valueSizeRet);
120 }
121 
122 Event::~Event() = default;
123 
callback(cl_int commandStatus)124 void Event::callback(cl_int commandStatus)
125 {
126     ASSERT(commandStatus >= 0 && commandStatus < 3);
127     const Callbacks callbacks = std::move(mCallbacks->at(commandStatus));
128     for (const CallbackData &data : callbacks)
129     {
130         data.first(this, commandStatus, data.second);
131     }
132     // This event can be released after the callback was called.
133     if (release())
134     {
135         delete this;
136     }
137 }
138 
Cast(cl_uint numEvents,const cl_event * eventList)139 EventPtrs Event::Cast(cl_uint numEvents, const cl_event *eventList)
140 {
141     EventPtrs events;
142     events.reserve(numEvents);
143     while (numEvents-- != 0u)
144     {
145         events.emplace_back(&(*eventList++)->cast<Event>());
146     }
147     return events;
148 }
149 
Event(Context & context)150 Event::Event(Context &context) : mContext(&context), mCommandType(CL_COMMAND_USER), mImpl(nullptr)
151 {
152     ANGLE_CL_IMPL_TRY(context.getImpl().createUserEvent(*this, &mImpl));
153 }
154 
Event(CommandQueue & queue,cl_command_type commandType,const rx::CLEventImpl::CreateFunc & createFunc)155 Event::Event(CommandQueue &queue,
156              cl_command_type commandType,
157              const rx::CLEventImpl::CreateFunc &createFunc)
158     : mContext(&queue.getContext()),
159       mCommandQueue(&queue),
160       mCommandType(commandType),
161       mImpl(createFunc(*this))
162 {}
163 
164 }  // namespace cl
165