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