• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2022 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 // frame_capture_utils.cpp:
7 //   ANGLE Frame capture common classes.
8 //
9 
10 #include "common/frame_capture_utils.h"
11 
12 namespace angle
13 {
14 namespace
15 {
16 // Keep the simplest nullptr string for easy C parsing.
17 constexpr char kNullPointerString[] = "0";
18 }  // anonymous namespace
19 
20 uint32_t ParamCapture::nextID = 0;
21 
ParamCapture()22 ParamCapture::ParamCapture()
23     : type(ParamType::TGLenum), enumGroup(gl::GLESEnum::AllEnums), uniqueID(nextID++)
24 {}
25 
ParamCapture(const char * nameIn,ParamType typeIn)26 ParamCapture::ParamCapture(const char *nameIn, ParamType typeIn)
27     : name(nameIn),
28       type(typeIn),
29       enumGroup(gl::GLESEnum::AllEnums),
30       bigGLEnum(gl::BigGLEnum::AllEnums),
31       uniqueID(nextID++)
32 {}
33 
34 ParamCapture::~ParamCapture() = default;
35 
ParamCapture(ParamCapture && other)36 ParamCapture::ParamCapture(ParamCapture &&other)
37     : type(ParamType::TGLenum),
38       enumGroup(gl::GLESEnum::AllEnums),
39       bigGLEnum(gl::BigGLEnum::AllEnums)
40 {
41     *this = std::move(other);
42 }
43 
operator =(ParamCapture && other)44 ParamCapture &ParamCapture::operator=(ParamCapture &&other)
45 {
46     std::swap(name, other.name);
47     std::swap(type, other.type);
48     std::swap(value, other.value);
49     std::swap(enumGroup, other.enumGroup);
50     std::swap(bigGLEnum, other.bigGLEnum);
51     std::swap(data, other.data);
52     std::swap(arrayClientPointerIndex, other.arrayClientPointerIndex);
53     std::swap(readBufferSizeBytes, other.readBufferSizeBytes);
54     std::swap(dataNElements, other.dataNElements);
55     std::swap(uniqueID, other.uniqueID);
56     return *this;
57 }
58 
ParamBuffer()59 ParamBuffer::ParamBuffer() {}
60 
61 ParamBuffer::~ParamBuffer() = default;
62 
ParamBuffer(ParamBuffer && other)63 ParamBuffer::ParamBuffer(ParamBuffer &&other)
64 {
65     *this = std::move(other);
66 }
67 
operator =(ParamBuffer && other)68 ParamBuffer &ParamBuffer::operator=(ParamBuffer &&other)
69 {
70     std::swap(mParamCaptures, other.mParamCaptures);
71     std::swap(mClientArrayDataParam, other.mClientArrayDataParam);
72     std::swap(mReadBufferSize, other.mReadBufferSize);
73     std::swap(mReturnValueCapture, other.mReturnValueCapture);
74     return *this;
75 }
76 
getParam(const char * paramName,ParamType paramType,int index)77 ParamCapture &ParamBuffer::getParam(const char *paramName, ParamType paramType, int index)
78 {
79     ParamCapture &capture = mParamCaptures[index];
80     ASSERT(capture.name == paramName);
81     ASSERT(capture.type == paramType);
82     return capture;
83 }
84 
getParam(const char * paramName,ParamType paramType,int index) const85 const ParamCapture &ParamBuffer::getParam(const char *paramName,
86                                           ParamType paramType,
87                                           int index) const
88 {
89     return const_cast<ParamBuffer *>(this)->getParam(paramName, paramType, index);
90 }
91 
getParamFlexName(const char * paramName1,const char * paramName2,ParamType paramType,int index)92 ParamCapture &ParamBuffer::getParamFlexName(const char *paramName1,
93                                             const char *paramName2,
94                                             ParamType paramType,
95                                             int index)
96 {
97     ParamCapture &capture = mParamCaptures[index];
98     ASSERT(capture.name == paramName1 || capture.name == paramName2);
99     ASSERT(capture.type == paramType);
100     return capture;
101 }
102 
getParamFlexName(const char * paramName1,const char * paramName2,ParamType paramType,int index) const103 const ParamCapture &ParamBuffer::getParamFlexName(const char *paramName1,
104                                                   const char *paramName2,
105                                                   ParamType paramType,
106                                                   int index) const
107 {
108     return const_cast<ParamBuffer *>(this)->getParamFlexName(paramName1, paramName2, paramType,
109                                                              index);
110 }
111 
addParam(ParamCapture && param)112 void ParamBuffer::addParam(ParamCapture &&param)
113 {
114     if (param.arrayClientPointerIndex != -1)
115     {
116         ASSERT(mClientArrayDataParam == -1);
117         mClientArrayDataParam = static_cast<int>(mParamCaptures.size());
118     }
119 
120     mReadBufferSize = std::max(param.readBufferSizeBytes, mReadBufferSize);
121     mParamCaptures.emplace_back(std::move(param));
122 }
123 
addReturnValue(ParamCapture && returnValue)124 void ParamBuffer::addReturnValue(ParamCapture &&returnValue)
125 {
126     mReturnValueCapture = std::move(returnValue);
127 }
128 
getNextParamName()129 const char *ParamBuffer::getNextParamName()
130 {
131     static const char *kParamNames[] = {"p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",
132                                         "p8",  "p9",  "p10", "p11", "p12", "p13", "p14", "p15",
133                                         "p16", "p17", "p18", "p19", "p20", "p21", "p22"};
134     ASSERT(mParamCaptures.size() < ArraySize(kParamNames));
135     return kParamNames[mParamCaptures.size()];
136 }
137 
getClientArrayPointerParameter()138 ParamCapture &ParamBuffer::getClientArrayPointerParameter()
139 {
140     ASSERT(hasClientArrayData());
141     return mParamCaptures[mClientArrayDataParam];
142 }
143 
CallCapture(EntryPoint entryPointIn,ParamBuffer && paramsIn)144 CallCapture::CallCapture(EntryPoint entryPointIn, ParamBuffer &&paramsIn)
145     : entryPoint(entryPointIn), params(std::move(paramsIn))
146 {}
147 
CallCapture(const std::string & customFunctionNameIn,ParamBuffer && paramsIn)148 CallCapture::CallCapture(const std::string &customFunctionNameIn, ParamBuffer &&paramsIn)
149     : entryPoint(EntryPoint::Invalid),
150       customFunctionName(customFunctionNameIn),
151       params(std::move(paramsIn))
152 {}
153 
154 CallCapture::~CallCapture() = default;
155 
CallCapture(CallCapture && other)156 CallCapture::CallCapture(CallCapture &&other)
157 {
158     *this = std::move(other);
159 }
160 
operator =(CallCapture && other)161 CallCapture &CallCapture::operator=(CallCapture &&other)
162 {
163     std::swap(entryPoint, other.entryPoint);
164     std::swap(customFunctionName, other.customFunctionName);
165     std::swap(params, other.params);
166     std::swap(isActive, other.isActive);
167     std::swap(contextID, other.contextID);
168     std::swap(isSyncPoint, other.isSyncPoint);
169     return *this;
170 }
171 
name() const172 const char *CallCapture::name() const
173 {
174     if (customFunctionName.empty())
175     {
176         ASSERT(entryPoint != EntryPoint::Invalid);
177         return angle::GetEntryPointName(entryPoint);
178     }
179     else
180     {
181         return customFunctionName.c_str();
182     }
183 }
184 
185 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLboolean value)186 void WriteParamValueReplay<ParamType::TGLboolean>(std::ostream &os,
187                                                   const CallCapture &call,
188                                                   GLboolean value)
189 {
190     switch (value)
191     {
192         case GL_TRUE:
193             os << "GL_TRUE";
194             break;
195         case GL_FALSE:
196             os << "GL_FALSE";
197             break;
198         default:
199             os << "0x" << std::hex << std::uppercase << GLint(value);
200     }
201 }
202 
203 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLboolean * value)204 void WriteParamValueReplay<ParamType::TGLbooleanPointer>(std::ostream &os,
205                                                          const CallCapture &call,
206                                                          GLboolean *value)
207 {
208     if (value == 0)
209     {
210         os << kNullPointerString;
211     }
212     else
213     {
214         os << "(GLboolean *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
215     }
216 }
217 
218 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const void * value)219 void WriteParamValueReplay<ParamType::TvoidConstPointer>(std::ostream &os,
220                                                          const CallCapture &call,
221                                                          const void *value)
222 {
223     if (value == 0)
224     {
225         os << kNullPointerString;
226     }
227     else
228     {
229         os << "(const void *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
230     }
231 }
232 
233 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,void * value)234 void WriteParamValueReplay<ParamType::TvoidPointer>(std::ostream &os,
235                                                     const CallCapture &call,
236                                                     void *value)
237 {
238     if (value == 0 || value == nullptr)
239     {
240         os << kNullPointerString;
241     }
242     else
243     {
244         os << "(void *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
245     }
246 }
247 
248 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLfloat * value)249 void WriteParamValueReplay<ParamType::TGLfloatConstPointer>(std::ostream &os,
250                                                             const CallCapture &call,
251                                                             const GLfloat *value)
252 {
253     if (value == 0)
254     {
255         os << kNullPointerString;
256     }
257     else
258     {
259         os << "(const GLfloat *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
260     }
261 }
262 
263 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLint * value)264 void WriteParamValueReplay<ParamType::TGLintConstPointer>(std::ostream &os,
265                                                           const CallCapture &call,
266                                                           const GLint *value)
267 {
268     if (value == 0)
269     {
270         os << kNullPointerString;
271     }
272     else
273     {
274         os << "(const GLint *)" << static_cast<int>(reinterpret_cast<intptr_t>(value));
275     }
276 }
277 
278 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLsizei * value)279 void WriteParamValueReplay<ParamType::TGLsizeiPointer>(std::ostream &os,
280                                                        const CallCapture &call,
281                                                        GLsizei *value)
282 {
283     if (value == 0)
284     {
285         os << kNullPointerString;
286     }
287     else
288     {
289         os << "(GLsizei *)" << static_cast<int>(reinterpret_cast<intptr_t>(value));
290     }
291 }
292 
293 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLuint * value)294 void WriteParamValueReplay<ParamType::TGLuintPointer>(std::ostream &os,
295                                                       const CallCapture &call,
296                                                       GLuint *value)
297 {
298     if (value == 0)
299     {
300         os << kNullPointerString;
301     }
302     else
303     {
304         os << "(GLuint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
305     }
306 }
307 
308 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const GLuint * value)309 void WriteParamValueReplay<ParamType::TGLuintConstPointer>(std::ostream &os,
310                                                            const CallCapture &call,
311                                                            const GLuint *value)
312 {
313     if (value == 0)
314     {
315         os << kNullPointerString;
316     }
317     else
318     {
319         os << "(const GLuint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
320     }
321 }
322 
323 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLDEBUGPROCKHR value)324 void WriteParamValueReplay<ParamType::TGLDEBUGPROCKHR>(std::ostream &os,
325                                                        const CallCapture &call,
326                                                        GLDEBUGPROCKHR value)
327 {}
328 
329 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLDEBUGPROC value)330 void WriteParamValueReplay<ParamType::TGLDEBUGPROC>(std::ostream &os,
331                                                     const CallCapture &call,
332                                                     GLDEBUGPROC value)
333 {}
334 
335 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::BufferID value)336 void WriteParamValueReplay<ParamType::TBufferID>(std::ostream &os,
337                                                  const CallCapture &call,
338                                                  gl::BufferID value)
339 {
340     os << "gBufferMap[" << value.value << "]";
341 }
342 
343 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::FenceNVID value)344 void WriteParamValueReplay<ParamType::TFenceNVID>(std::ostream &os,
345                                                   const CallCapture &call,
346                                                   gl::FenceNVID value)
347 {
348     os << "gFenceNVMap[" << value.value << "]";
349 }
350 
351 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::FramebufferID value)352 void WriteParamValueReplay<ParamType::TFramebufferID>(std::ostream &os,
353                                                       const CallCapture &call,
354                                                       gl::FramebufferID value)
355 {
356     os << "gFramebufferMapPerContext[" << call.contextID.value << "][" << value.value << "]";
357 }
358 
359 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::MemoryObjectID value)360 void WriteParamValueReplay<ParamType::TMemoryObjectID>(std::ostream &os,
361                                                        const CallCapture &call,
362                                                        gl::MemoryObjectID value)
363 {
364     os << "gMemoryObjectMap[" << value.value << "]";
365 }
366 
367 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ProgramPipelineID value)368 void WriteParamValueReplay<ParamType::TProgramPipelineID>(std::ostream &os,
369                                                           const CallCapture &call,
370                                                           gl::ProgramPipelineID value)
371 {
372     os << "gProgramPipelineMap[" << value.value << "]";
373 }
374 
375 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::QueryID value)376 void WriteParamValueReplay<ParamType::TQueryID>(std::ostream &os,
377                                                 const CallCapture &call,
378                                                 gl::QueryID value)
379 {
380     os << "gQueryMap[" << value.value << "]";
381 }
382 
383 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::RenderbufferID value)384 void WriteParamValueReplay<ParamType::TRenderbufferID>(std::ostream &os,
385                                                        const CallCapture &call,
386                                                        gl::RenderbufferID value)
387 {
388     os << "gRenderbufferMap[" << value.value << "]";
389 }
390 
391 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SamplerID value)392 void WriteParamValueReplay<ParamType::TSamplerID>(std::ostream &os,
393                                                   const CallCapture &call,
394                                                   gl::SamplerID value)
395 {
396     os << "gSamplerMap[" << value.value << "]";
397 }
398 
399 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SemaphoreID value)400 void WriteParamValueReplay<ParamType::TSemaphoreID>(std::ostream &os,
401                                                     const CallCapture &call,
402                                                     gl::SemaphoreID value)
403 {
404     os << "gSemaphoreMap[" << value.value << "]";
405 }
406 
407 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ShaderProgramID value)408 void WriteParamValueReplay<ParamType::TShaderProgramID>(std::ostream &os,
409                                                         const CallCapture &call,
410                                                         gl::ShaderProgramID value)
411 {
412     os << "gShaderProgramMap[" << value.value << "]";
413 }
414 
415 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::SyncID value)416 void WriteParamValueReplay<ParamType::TSyncID>(std::ostream &os,
417                                                const CallCapture &call,
418                                                gl::SyncID value)
419 {
420     os << "gSyncMap2[" << value.value << "]";
421 }
422 
423 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::TextureID value)424 void WriteParamValueReplay<ParamType::TTextureID>(std::ostream &os,
425                                                   const CallCapture &call,
426                                                   gl::TextureID value)
427 {
428     os << "gTextureMap[" << value.value << "]";
429 }
430 
431 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::TransformFeedbackID value)432 void WriteParamValueReplay<ParamType::TTransformFeedbackID>(std::ostream &os,
433                                                             const CallCapture &call,
434                                                             gl::TransformFeedbackID value)
435 {
436     os << "gTransformFeedbackMap[" << value.value << "]";
437 }
438 
439 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::VertexArrayID value)440 void WriteParamValueReplay<ParamType::TVertexArrayID>(std::ostream &os,
441                                                       const CallCapture &call,
442                                                       gl::VertexArrayID value)
443 {
444     os << "gVertexArrayMap[" << value.value << "]";
445 }
446 
447 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::UniformLocation value)448 void WriteParamValueReplay<ParamType::TUniformLocation>(std::ostream &os,
449                                                         const CallCapture &call,
450                                                         gl::UniformLocation value)
451 {
452     if (value.value == -1)
453     {
454         os << "-1";
455         return;
456     }
457 
458     os << "gUniformLocations[";
459 
460     // Find the program from the call parameters.
461     std::vector<gl::ShaderProgramID> shaderProgramIDs;
462     if (FindResourceIDsInCall<gl::ShaderProgramID>(call, shaderProgramIDs))
463     {
464         ASSERT(shaderProgramIDs.size() == 1);
465         os << shaderProgramIDs[0].value;
466     }
467     else
468     {
469         os << "gCurrentProgram";
470     }
471 
472     os << "][" << value.value << "]";
473 }
474 
475 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::UniformBlockIndex value)476 void WriteParamValueReplay<ParamType::TUniformBlockIndex>(std::ostream &os,
477                                                           const CallCapture &call,
478                                                           gl::UniformBlockIndex value)
479 {
480     // We do not support directly using uniform block indexes due to their multiple indirections.
481     // Use CaptureCustomUniformBlockBinding if you end up hitting this assertion.
482     UNREACHABLE();
483 }
484 
485 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLubyte value)486 void WriteParamValueReplay<ParamType::TGLubyte>(std::ostream &os,
487                                                 const CallCapture &call,
488                                                 GLubyte value)
489 {
490     const int v = value;
491     os << v;
492 }
493 
494 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLDEBUGPROCKHR value)495 void WriteParamValueReplay<ParamType::TEGLDEBUGPROCKHR>(std::ostream &os,
496                                                         const CallCapture &call,
497                                                         EGLDEBUGPROCKHR value)
498 {
499     // It's not necessary to implement correct capture for these types.
500     os << "0";
501 }
502 
503 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLGetBlobFuncANDROID value)504 void WriteParamValueReplay<ParamType::TEGLGetBlobFuncANDROID>(std::ostream &os,
505                                                               const CallCapture &call,
506                                                               EGLGetBlobFuncANDROID value)
507 {
508     // It's not necessary to implement correct capture for these types.
509     os << "0";
510 }
511 
512 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLSetBlobFuncANDROID value)513 void WriteParamValueReplay<ParamType::TEGLSetBlobFuncANDROID>(std::ostream &os,
514                                                               const CallCapture &call,
515                                                               EGLSetBlobFuncANDROID value)
516 {
517     // It's not necessary to implement correct capture for these types.
518     os << "0";
519 }
520 
521 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::Config * value)522 void WriteParamValueReplay<ParamType::Tegl_ConfigPointer>(std::ostream &os,
523                                                           const CallCapture &call,
524                                                           egl::Config *value)
525 {
526     os << "EGL_NO_CONFIG_KHR";
527 }
528 
529 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::SurfaceID value)530 void WriteParamValueReplay<ParamType::TSurfaceID>(std::ostream &os,
531                                                   const CallCapture &call,
532                                                   egl::SurfaceID value)
533 {
534     os << "gSurfaceMap2[" << value.value << "]";
535 }
536 
537 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,gl::ContextID value)538 void WriteParamValueReplay<ParamType::TContextID>(std::ostream &os,
539                                                   const CallCapture &call,
540                                                   gl::ContextID value)
541 {
542     os << "gContextMap2[" << value.value << "]";
543 }
544 
545 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::Display * value)546 void WriteParamValueReplay<ParamType::Tegl_DisplayPointer>(std::ostream &os,
547                                                            const CallCapture &call,
548                                                            egl::Display *value)
549 {
550     os << "gEGLDisplay";
551 }
552 
553 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::ImageID value)554 void WriteParamValueReplay<ParamType::TImageID>(std::ostream &os,
555                                                 const CallCapture &call,
556                                                 egl::ImageID value)
557 {
558     os << "gEGLImageMap2[" << value.value << "]";
559 }
560 
561 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLClientBuffer value)562 void WriteParamValueReplay<ParamType::TEGLClientBuffer>(std::ostream &os,
563                                                         const CallCapture &call,
564                                                         EGLClientBuffer value)
565 {
566     os << value;
567 }
568 
569 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,egl::SyncID value)570 void WriteParamValueReplay<ParamType::Tegl_SyncID>(std::ostream &os,
571                                                    const CallCapture &call,
572                                                    egl::SyncID value)
573 {
574     os << "gEGLSyncMap[" << value.value << "]";
575 }
576 
577 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLAttrib * value)578 void WriteParamValueReplay<ParamType::TEGLAttribPointer>(std::ostream &os,
579                                                          const CallCapture &call,
580                                                          EGLAttrib *value)
581 {
582     if (value == 0)
583     {
584         os << kNullPointerString;
585     }
586     else
587     {
588         os << "(EGLAttrib *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
589     }
590 }
591 
592 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const EGLAttrib * value)593 void WriteParamValueReplay<ParamType::TEGLAttribConstPointer>(std::ostream &os,
594                                                               const CallCapture &call,
595                                                               const EGLAttrib *value)
596 {
597     if (value == 0)
598     {
599         os << kNullPointerString;
600     }
601     else
602     {
603         os << "(const EGLAttrib *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
604     }
605 }
606 
607 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const EGLint * value)608 void WriteParamValueReplay<ParamType::TEGLintConstPointer>(std::ostream &os,
609                                                            const CallCapture &call,
610                                                            const EGLint *value)
611 {
612     if (value == 0)
613     {
614         os << kNullPointerString;
615     }
616     else
617     {
618         os << "(const EGLint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
619     }
620 }
621 
622 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLint * value)623 void WriteParamValueReplay<ParamType::TEGLintPointer>(std::ostream &os,
624                                                       const CallCapture &call,
625                                                       EGLint *value)
626 {
627     if (value == 0)
628     {
629         os << kNullPointerString;
630     }
631     else
632     {
633         os << "(const EGLint *)" << static_cast<int>(reinterpret_cast<uintptr_t>(value));
634     }
635 }
636 
637 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLTime value)638 void WriteParamValueReplay<ParamType::TEGLTime>(std::ostream &os,
639                                                 const CallCapture &call,
640                                                 EGLTime value)
641 {
642     os << value << "ul";
643 }
644 
645 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,EGLTimeKHR value)646 void WriteParamValueReplay<ParamType::TEGLTimeKHR>(std::ostream &os,
647                                                    const CallCapture &call,
648                                                    EGLTimeKHR value)
649 {
650     os << value << "ul";
651 }
652 
653 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLGETBLOBPROCANGLE value)654 void WriteParamValueReplay<ParamType::TGLGETBLOBPROCANGLE>(std::ostream &os,
655                                                            const CallCapture &call,
656                                                            GLGETBLOBPROCANGLE value)
657 {
658     // It's not necessary to implement correct capture for these types.
659     os << "0";
660 }
661 
662 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,GLSETBLOBPROCANGLE value)663 void WriteParamValueReplay<ParamType::TGLSETBLOBPROCANGLE>(std::ostream &os,
664                                                            const CallCapture &call,
665                                                            GLSETBLOBPROCANGLE value)
666 {
667     // It's not necessary to implement correct capture for these types.
668     os << "0";
669 }
670 
671 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const char * value)672 void WriteParamValueReplay<ParamType::TcharConstPointer>(std::ostream &os,
673                                                          const CallCapture &call,
674                                                          const char *value)
675 {
676     if (value)
677     {
678         os << "\"" << value << "\"";
679     }
680     else
681     {
682         os << NULL;
683     }
684 }
685 
686 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,size_t * value)687 void WriteParamValueReplay<ParamType::Tsize_tPointer>(std::ostream &os,
688                                                       const CallCapture &call,
689                                                       size_t *value)
690 {
691     ASSERT(!value);
692     os << "NULL";
693 }
694 
695 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,size_t const * value)696 void WriteParamValueReplay<ParamType::Tsize_tConstPointer>(std::ostream &os,
697                                                            const CallCapture &call,
698                                                            size_t const *value)
699 {
700     ASSERT(!value);
701     os << "NULL";
702 }
703 
704 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const char ** value)705 void WriteParamValueReplay<ParamType::TcharConstPointerPointer>(std::ostream &os,
706                                                                 const CallCapture &call,
707                                                                 const char **value)
708 {
709     ASSERT(!value);
710     os << "NULL";
711 }
712 
713 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const unsigned char ** value)714 void WriteParamValueReplay<ParamType::TcharUnsignedConstPointerPointer>(std::ostream &os,
715                                                                         const CallCapture &call,
716                                                                         const unsigned char **value)
717 {
718     ASSERT(!value);
719     os << "NULL";
720 }
721 
722 #ifdef ANGLE_ENABLE_CL
723 
724 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_platform_id * value)725 void WriteParamValueReplay<ParamType::Tcl_platform_idPointer>(std::ostream &os,
726                                                               const CallCapture &call,
727                                                               cl_platform_id *value)
728 {
729     ASSERT(!value);
730     os << "NULL";
731 }
732 
733 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_uint * value)734 void WriteParamValueReplay<ParamType::Tcl_uintPointer>(std::ostream &os,
735                                                        const CallCapture &call,
736                                                        cl_uint *value)
737 {
738     ASSERT(!value);
739     os << "NULL";
740 }
741 
742 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_device_id * value)743 void WriteParamValueReplay<ParamType::Tcl_device_idPointer>(std::ostream &os,
744                                                             const CallCapture &call,
745                                                             cl_device_id *value)
746 {
747     ASSERT(!value);
748     os << "NULL";
749 }
750 
751 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_properties const * value)752 void WriteParamValueReplay<ParamType::Tcl_context_propertiesConstPointer>(
753     std::ostream &os,
754     const CallCapture &call,
755     cl_context_properties const *value)
756 {
757     ASSERT(!value);
758     os << "NULL";
759 }
760 
761 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_event * value)762 void WriteParamValueReplay<ParamType::Tcl_eventPointer>(std::ostream &os,
763                                                         const CallCapture &call,
764                                                         cl_event *value)
765 {
766     ASSERT(!value);
767     os << "NULL";
768 }
769 
770 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_event const * value)771 void WriteParamValueReplay<ParamType::Tcl_eventConstPointer>(std::ostream &os,
772                                                              const CallCapture &call,
773                                                              cl_event const *value)
774 {
775     ASSERT(!value);
776     os << "NULL";
777 }
778 
779 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_device_id const * value)780 void WriteParamValueReplay<ParamType::Tcl_device_idConstPointer>(std::ostream &os,
781                                                                  const CallCapture &call,
782                                                                  cl_device_id const *value)
783 {
784     ASSERT(!value);
785     os << "NULL";
786 }
787 
788 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_image_format * value)789 void WriteParamValueReplay<ParamType::Tcl_image_formatPointer>(std::ostream &os,
790                                                                const CallCapture &call,
791                                                                cl_image_format *value)
792 {
793     ASSERT(!value);
794     os << "NULL";
795 }
796 
797 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_int * value)798 void WriteParamValueReplay<ParamType::Tcl_intPointer>(std::ostream &os,
799                                                       const CallCapture &call,
800                                                       cl_int *value)
801 {
802     ASSERT(!value);
803     os << "NULL";
804 }
805 
806 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_queue_properties * value)807 void WriteParamValueReplay<ParamType::Tcl_queue_propertiesConstPointer>(
808     std::ostream &os,
809     const CallCapture &call,
810     const cl_queue_properties *value)
811 {
812     ASSERT(!value);
813     os << "NULL";
814 }
815 
816 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_command_queue_properties * value)817 void WriteParamValueReplay<ParamType::Tcl_command_queue_propertiesPointer>(
818     std::ostream &os,
819     const CallCapture &call,
820     const cl_command_queue_properties *value)
821 {
822     ASSERT(!value);
823     os << "NULL";
824 }
825 
826 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_device_partition_property * value)827 void WriteParamValueReplay<ParamType::Tcl_device_partition_propertyConstPointer>(
828     std::ostream &os,
829     const CallCapture &call,
830     const cl_device_partition_property *value)
831 {
832     ASSERT(!value);
833     os << "NULL";
834 }
835 
836 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_program * value)837 void WriteParamValueReplay<ParamType::Tcl_programConstPointer>(std::ostream &os,
838                                                                const CallCapture &call,
839                                                                const cl_program *value)
840 {
841     ASSERT(!value);
842     os << "NULL";
843 }
844 
845 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,const cl_pipe_properties * value)846 void WriteParamValueReplay<ParamType::Tcl_pipe_propertiesConstPointer>(
847     std::ostream &os,
848     const CallCapture &call,
849     const cl_pipe_properties *value)
850 {
851     ASSERT(!value);
852     os << "NULL";
853 }
854 
855 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_ulong * value)856 void WriteParamValueReplay<ParamType::Tcl_ulongPointer>(std::ostream &os,
857                                                         const CallCapture &call,
858                                                         cl_ulong *value)
859 {
860     ASSERT(!value);
861     os << "NULL";
862 }
863 
864 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_callback_func_type value)865 void WriteParamValueReplay<ParamType::Tcl_callback_func_type>(std::ostream &os,
866                                                               const CallCapture &call,
867                                                               cl_callback_func_type value)
868 {
869     os << "NULL";
870 }
871 
872 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_destructor_func_type value)873 void WriteParamValueReplay<ParamType::Tcl_context_destructor_func_type>(
874     std::ostream &os,
875     const CallCapture &call,
876     cl_context_destructor_func_type value)
877 {
878     os << "NULL";
879 }
880 
881 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_context_func_type value)882 void WriteParamValueReplay<ParamType::Tcl_context_func_type>(std::ostream &os,
883                                                              const CallCapture &call,
884                                                              cl_context_func_type value)
885 {
886     os << "NULL";
887 }
888 
889 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_mem_destructor_func_type value)890 void WriteParamValueReplay<ParamType::Tcl_mem_destructor_func_type>(
891     std::ostream &os,
892     const CallCapture &call,
893     cl_mem_destructor_func_type value)
894 {
895     os << "NULL";
896 }
897 
898 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_program_func_type value)899 void WriteParamValueReplay<ParamType::Tcl_program_func_type>(std::ostream &os,
900                                                              const CallCapture &call,
901                                                              cl_program_func_type value)
902 {
903     os << "NULL";
904 }
905 
906 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_svm_free_callback_func_type value)907 void WriteParamValueReplay<ParamType::Tcl_svm_free_callback_func_type>(
908     std::ostream &os,
909     const CallCapture &call,
910     cl_svm_free_callback_func_type value)
911 {
912     os << "NULL";
913 }
914 
915 template <>
WriteParamValueReplay(std::ostream & os,const CallCapture & call,cl_void_func_type value)916 void WriteParamValueReplay<ParamType::Tcl_void_func_type>(std::ostream &os,
917                                                           const CallCapture &call,
918                                                           cl_void_func_type value)
919 {
920     os << "NULL";
921 }
922 
923 #endif
924 
925 template <typename ParamValueType>
FindResourceIDsInCall(const CallCapture & call,std::vector<ParamValueType> & idsOut)926 bool FindResourceIDsInCall(const CallCapture &call, std::vector<ParamValueType> &idsOut)
927 {
928     const ParamType paramType = ParamValueTrait<ParamValueType>::typeID;
929     for (const ParamCapture &param : call.params.getParamCaptures())
930     {
931         if (param.type == paramType)
932         {
933             const ParamValueType id = AccessParamValue<ParamValueType>(paramType, param.value);
934             idsOut.push_back(id);
935         }
936     }
937 
938     return !idsOut.empty();
939 }
940 
941 // Explicit instantiation
942 template bool FindResourceIDsInCall<gl::TextureID>(const CallCapture &call,
943                                                    std::vector<gl::TextureID> &idsOut);
944 template bool FindResourceIDsInCall<gl::ShaderProgramID>(const CallCapture &call,
945                                                          std::vector<gl::ShaderProgramID> &idsOut);
946 }  // namespace angle
947