xref: /aosp_15_r20/external/angle/util/capture/trace_fixture.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 // trace_fixture.cpp:
7 //   Common code for the ANGLE trace replays.
8 //
9 
10 #include "trace_fixture.h"
11 
12 #include "angle_trace_gl.h"
13 
14 #include <string>
15 
16 namespace
17 {
UpdateResourceMap(GLuint * resourceMap,GLuint id,GLsizei readBufferOffset)18 void UpdateResourceMap(GLuint *resourceMap, GLuint id, GLsizei readBufferOffset)
19 {
20     GLuint returnedID;
21     memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
22     resourceMap[id] = returnedID;
23 }
24 
UpdateResourceMapPerContext(GLuint ** resourceArray,GLuint contextId,GLuint id,GLsizei readBufferOffset)25 void UpdateResourceMapPerContext(GLuint **resourceArray,
26                                  GLuint contextId,
27                                  GLuint id,
28                                  GLsizei readBufferOffset)
29 {
30     GLuint returnedID;
31     memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
32     resourceArray[contextId][id] = returnedID;
33 }
34 
35 uint32_t gMaxContexts                  = 0;
36 angle::TraceCallbacks *gTraceCallbacks = nullptr;
37 
GetClientBuffer(EGLenum target,uintptr_t key)38 EGLClientBuffer GetClientBuffer(EGLenum target, uintptr_t key)
39 {
40     switch (target)
41     {
42         case EGL_GL_TEXTURE_2D:
43         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
44         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
45         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
46         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
47         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
48         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
49         case EGL_GL_TEXTURE_3D:
50         {
51             uintptr_t id = static_cast<uintptr_t>(gTextureMap[key]);
52             return reinterpret_cast<EGLClientBuffer>(id);
53         }
54         case EGL_GL_RENDERBUFFER:
55         {
56             uintptr_t id = static_cast<uintptr_t>(gRenderbufferMap[key]);
57             return reinterpret_cast<EGLClientBuffer>(id);
58         }
59         default:
60         {
61             const auto &iData = gClientBufferMap.find(key);
62             return iData != gClientBufferMap.end() ? iData->second : nullptr;
63         }
64     }
65 }
66 
67 ValidateSerializedStateCallback gValidateSerializedStateCallback;
68 std::unordered_map<GLuint, std::vector<GLint>> gInternalUniformLocationsMap;
69 
70 constexpr size_t kMaxClientArrays = 16;
71 }  // namespace
72 
73 GLint **gUniformLocations;
74 GLuint gCurrentProgram = 0;
75 
76 // TODO(jmadill): Hide from the traces. http://anglebug.com/42266223
77 BlockIndexesMap gUniformBlockIndexes;
78 
UpdateUniformLocation(GLuint program,const char * name,GLint location,GLint count)79 void UpdateUniformLocation(GLuint program, const char *name, GLint location, GLint count)
80 {
81     std::vector<GLint> &programLocations = gInternalUniformLocationsMap[program];
82     if (static_cast<GLint>(programLocations.size()) < location + count)
83     {
84         programLocations.resize(location + count, 0);
85     }
86     GLuint mappedProgramID = gShaderProgramMap[program];
87     for (GLint arrayIndex = 0; arrayIndex < count; ++arrayIndex)
88     {
89         programLocations[location + arrayIndex] =
90             glGetUniformLocation(mappedProgramID, name) + arrayIndex;
91     }
92     gUniformLocations[program] = programLocations.data();
93 }
94 
DeleteUniformLocations(GLuint program)95 void DeleteUniformLocations(GLuint program)
96 {
97     // No-op. We leave uniform locations around so deleted current programs can still use them.
98 }
99 
UpdateUniformBlockIndex(GLuint program,const char * name,GLuint index)100 void UpdateUniformBlockIndex(GLuint program, const char *name, GLuint index)
101 {
102     gUniformBlockIndexes[program][index] = glGetUniformBlockIndex(program, name);
103 }
104 
UniformBlockBinding(GLuint program,GLuint uniformblockIndex,GLuint binding)105 void UniformBlockBinding(GLuint program, GLuint uniformblockIndex, GLuint binding)
106 {
107     glUniformBlockBinding(gShaderProgramMap[program],
108                           gUniformBlockIndexes[gShaderProgramMap[program]][uniformblockIndex],
109                           binding);
110 }
111 
UpdateCurrentProgram(GLuint program)112 void UpdateCurrentProgram(GLuint program)
113 {
114     gCurrentProgram = program;
115 }
116 
117 uint8_t *gBinaryData;
118 uint8_t *gReadBuffer;
119 uint8_t *gClientArrays[kMaxClientArrays];
120 GLuint *gResourceIDBuffer;
121 SyncResourceMap gSyncMap;
122 ContextMap gContextMap;
123 GLuint gShareContextId;
124 GLuint *gBufferMap;
125 GLuint *gFenceNVMap;
126 GLuint *gFramebufferMap;
127 GLuint **gFramebufferMapPerContext;
128 GLuint *gMemoryObjectMap;
129 GLuint *gProgramPipelineMap;
130 GLuint *gQueryMap;
131 GLuint *gRenderbufferMap;
132 GLuint *gSamplerMap;
133 GLuint *gSemaphoreMap;
134 GLuint *gShaderProgramMap;
135 GLuint *gTextureMap;
136 GLuint *gTransformFeedbackMap;
137 GLuint *gVertexArrayMap;
138 
139 // TODO(jmadill): Consolidate. http://anglebug.com/42266223
140 ClientBufferMap gClientBufferMap;
141 EGLImageMap gEGLImageMap;
142 SurfaceMap gSurfaceMap;
143 
144 GLeglImageOES *gEGLImageMap2;
145 GLuint *gEGLImageMap2Resources;
146 EGLSurface *gSurfaceMap2;
147 EGLContext *gContextMap2;
148 GLsync *gSyncMap2;
149 EGLSync *gEGLSyncMap;
150 EGLDisplay gEGLDisplay;
151 
152 std::string gBinaryDataDir = ".";
153 
154 angle::ReplayResourceMode gReplayResourceMode = angle::ReplayResourceMode::Active;
155 
156 template <typename T>
AllocateZeroedValues(size_t count)157 T *AllocateZeroedValues(size_t count)
158 {
159     T *mem = new T[count + 1];
160     memset(mem, 0, sizeof(T) * (count + 1));
161     return mem;
162 }
163 
AllocateZeroedUints(size_t count)164 GLuint *AllocateZeroedUints(size_t count)
165 {
166     return AllocateZeroedValues<GLuint>(count);
167 }
168 
InitializeReplay4(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize,size_t resourceIDBufferSize,GLuint contextId,uint32_t maxBuffer,uint32_t maxContext,uint32_t maxFenceNV,uint32_t maxFramebuffer,uint32_t maxImage,uint32_t maxMemoryObject,uint32_t maxProgramPipeline,uint32_t maxQuery,uint32_t maxRenderbuffer,uint32_t maxSampler,uint32_t maxSemaphore,uint32_t maxShaderProgram,uint32_t maxSurface,uint32_t maxSync,uint32_t maxTexture,uint32_t maxTransformFeedback,uint32_t maxVertexArray,GLuint maxEGLSyncID)169 void InitializeReplay4(const char *binaryDataFileName,
170                        size_t maxClientArraySize,
171                        size_t readBufferSize,
172                        size_t resourceIDBufferSize,
173                        GLuint contextId,
174                        uint32_t maxBuffer,
175                        uint32_t maxContext,
176                        uint32_t maxFenceNV,
177                        uint32_t maxFramebuffer,
178                        uint32_t maxImage,
179                        uint32_t maxMemoryObject,
180                        uint32_t maxProgramPipeline,
181                        uint32_t maxQuery,
182                        uint32_t maxRenderbuffer,
183                        uint32_t maxSampler,
184                        uint32_t maxSemaphore,
185                        uint32_t maxShaderProgram,
186                        uint32_t maxSurface,
187                        uint32_t maxSync,
188                        uint32_t maxTexture,
189                        uint32_t maxTransformFeedback,
190                        uint32_t maxVertexArray,
191                        GLuint maxEGLSyncID)
192 {
193     InitializeReplay3(binaryDataFileName, maxClientArraySize, readBufferSize, resourceIDBufferSize,
194                       contextId, maxBuffer, maxContext, maxFenceNV, maxFramebuffer, maxImage,
195                       maxMemoryObject, maxProgramPipeline, maxQuery, maxRenderbuffer, maxSampler,
196                       maxSemaphore, maxShaderProgram, maxSurface, maxSync, maxTexture,
197                       maxTransformFeedback, maxVertexArray);
198     gEGLSyncMap = AllocateZeroedValues<EGLSync>(maxEGLSyncID);
199     gEGLDisplay = eglGetCurrentDisplay();
200 
201     gMaxContexts              = maxContext + 1;
202     gFramebufferMapPerContext = new GLuint *[gMaxContexts];
203     memset(gFramebufferMapPerContext, 0, sizeof(GLuint *) * (gMaxContexts));
204     for (uint8_t i = 0; i < gMaxContexts; i++)
205     {
206         gFramebufferMapPerContext[i] = AllocateZeroedValues<GLuint>(maxFramebuffer);
207     }
208 }
209 
InitializeReplay3(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize,size_t resourceIDBufferSize,GLuint contextId,uint32_t maxBuffer,uint32_t maxContext,uint32_t maxFenceNV,uint32_t maxFramebuffer,uint32_t maxImage,uint32_t maxMemoryObject,uint32_t maxProgramPipeline,uint32_t maxQuery,uint32_t maxRenderbuffer,uint32_t maxSampler,uint32_t maxSemaphore,uint32_t maxShaderProgram,uint32_t maxSurface,uint32_t maxSync,uint32_t maxTexture,uint32_t maxTransformFeedback,uint32_t maxVertexArray)210 void InitializeReplay3(const char *binaryDataFileName,
211                        size_t maxClientArraySize,
212                        size_t readBufferSize,
213                        size_t resourceIDBufferSize,
214                        GLuint contextId,
215                        uint32_t maxBuffer,
216                        uint32_t maxContext,
217                        uint32_t maxFenceNV,
218                        uint32_t maxFramebuffer,
219                        uint32_t maxImage,
220                        uint32_t maxMemoryObject,
221                        uint32_t maxProgramPipeline,
222                        uint32_t maxQuery,
223                        uint32_t maxRenderbuffer,
224                        uint32_t maxSampler,
225                        uint32_t maxSemaphore,
226                        uint32_t maxShaderProgram,
227                        uint32_t maxSurface,
228                        uint32_t maxSync,
229                        uint32_t maxTexture,
230                        uint32_t maxTransformFeedback,
231                        uint32_t maxVertexArray)
232 {
233     InitializeReplay2(binaryDataFileName, maxClientArraySize, readBufferSize, contextId, maxBuffer,
234                       maxContext, maxFenceNV, maxFramebuffer, maxImage, maxMemoryObject,
235                       maxProgramPipeline, maxQuery, maxRenderbuffer, maxSampler, maxSemaphore,
236                       maxShaderProgram, maxSurface, maxTexture, maxTransformFeedback,
237                       maxVertexArray);
238 
239     gSyncMap2         = AllocateZeroedValues<GLsync>(maxSync);
240     gResourceIDBuffer = AllocateZeroedUints(resourceIDBufferSize);
241 }
242 
InitializeReplay2(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize,GLuint contextId,uint32_t maxBuffer,uint32_t maxContext,uint32_t maxFenceNV,uint32_t maxFramebuffer,uint32_t maxImage,uint32_t maxMemoryObject,uint32_t maxProgramPipeline,uint32_t maxQuery,uint32_t maxRenderbuffer,uint32_t maxSampler,uint32_t maxSemaphore,uint32_t maxShaderProgram,uint32_t maxSurface,uint32_t maxTexture,uint32_t maxTransformFeedback,uint32_t maxVertexArray)243 void InitializeReplay2(const char *binaryDataFileName,
244                        size_t maxClientArraySize,
245                        size_t readBufferSize,
246                        GLuint contextId,
247                        uint32_t maxBuffer,
248                        uint32_t maxContext,
249                        uint32_t maxFenceNV,
250                        uint32_t maxFramebuffer,
251                        uint32_t maxImage,
252                        uint32_t maxMemoryObject,
253                        uint32_t maxProgramPipeline,
254                        uint32_t maxQuery,
255                        uint32_t maxRenderbuffer,
256                        uint32_t maxSampler,
257                        uint32_t maxSemaphore,
258                        uint32_t maxShaderProgram,
259                        uint32_t maxSurface,
260                        uint32_t maxTexture,
261                        uint32_t maxTransformFeedback,
262                        uint32_t maxVertexArray)
263 {
264     InitializeReplay(binaryDataFileName, maxClientArraySize, readBufferSize, maxBuffer, maxFenceNV,
265                      maxFramebuffer, maxMemoryObject, maxProgramPipeline, maxQuery, maxRenderbuffer,
266                      maxSampler, maxSemaphore, maxShaderProgram, maxTexture, maxTransformFeedback,
267                      maxVertexArray);
268 
269     gContextMap2           = AllocateZeroedValues<EGLContext>(maxContext);
270     gEGLImageMap2          = AllocateZeroedValues<EGLImage>(maxImage);
271     gEGLImageMap2Resources = AllocateZeroedValues<GLuint>(maxImage);
272     gSurfaceMap2           = AllocateZeroedValues<EGLSurface>(maxSurface);
273 
274     gContextMap2[0]         = EGL_NO_CONTEXT;
275     gShareContextId         = contextId;
276     gContextMap2[contextId] = eglGetCurrentContext();
277 }
278 
InitializeReplay(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize,uint32_t maxBuffer,uint32_t maxFenceNV,uint32_t maxFramebuffer,uint32_t maxMemoryObject,uint32_t maxProgramPipeline,uint32_t maxQuery,uint32_t maxRenderbuffer,uint32_t maxSampler,uint32_t maxSemaphore,uint32_t maxShaderProgram,uint32_t maxTexture,uint32_t maxTransformFeedback,uint32_t maxVertexArray)279 void InitializeReplay(const char *binaryDataFileName,
280                       size_t maxClientArraySize,
281                       size_t readBufferSize,
282                       uint32_t maxBuffer,
283                       uint32_t maxFenceNV,
284                       uint32_t maxFramebuffer,
285                       uint32_t maxMemoryObject,
286                       uint32_t maxProgramPipeline,
287                       uint32_t maxQuery,
288                       uint32_t maxRenderbuffer,
289                       uint32_t maxSampler,
290                       uint32_t maxSemaphore,
291                       uint32_t maxShaderProgram,
292                       uint32_t maxTexture,
293                       uint32_t maxTransformFeedback,
294                       uint32_t maxVertexArray)
295 {
296     gBinaryData = gTraceCallbacks->LoadBinaryData(binaryDataFileName);
297 
298     for (uint8_t *&clientArray : gClientArrays)
299     {
300         clientArray = new uint8_t[maxClientArraySize];
301     }
302 
303     gReadBuffer = new uint8_t[readBufferSize];
304 
305     gBufferMap            = AllocateZeroedUints(maxBuffer);
306     gFenceNVMap           = AllocateZeroedUints(maxFenceNV);
307     gFramebufferMap       = AllocateZeroedUints(maxFramebuffer);
308     gMemoryObjectMap      = AllocateZeroedUints(maxMemoryObject);
309     gProgramPipelineMap   = AllocateZeroedUints(maxProgramPipeline);
310     gQueryMap             = AllocateZeroedUints(maxQuery);
311     gRenderbufferMap      = AllocateZeroedUints(maxRenderbuffer);
312     gSamplerMap           = AllocateZeroedUints(maxSampler);
313     gSemaphoreMap         = AllocateZeroedUints(maxSemaphore);
314     gShaderProgramMap     = AllocateZeroedUints(maxShaderProgram);
315     gTextureMap           = AllocateZeroedUints(maxTexture);
316     gTransformFeedbackMap = AllocateZeroedUints(maxTransformFeedback);
317     gVertexArrayMap       = AllocateZeroedUints(maxVertexArray);
318 
319     gUniformLocations = new GLint *[maxShaderProgram + 1];
320     memset(gUniformLocations, 0, sizeof(GLint *) * (maxShaderProgram + 1));
321 
322     gContextMap[0] = EGL_NO_CONTEXT;
323 }
324 
FinishReplay()325 void FinishReplay()
326 {
327     for (uint8_t *&clientArray : gClientArrays)
328     {
329         delete[] clientArray;
330     }
331     delete[] gReadBuffer;
332     delete[] gResourceIDBuffer;
333     delete[] gBufferMap;
334     delete[] gContextMap2;
335     delete[] gEGLImageMap2;
336     delete[] gEGLSyncMap;
337     delete[] gRenderbufferMap;
338     delete[] gTextureMap;
339     delete[] gFramebufferMap;
340     delete[] gShaderProgramMap;
341     delete[] gFenceNVMap;
342     delete[] gMemoryObjectMap;
343     delete[] gProgramPipelineMap;
344     delete[] gQueryMap;
345     delete[] gSamplerMap;
346     delete[] gSemaphoreMap;
347     delete[] gSurfaceMap2;
348     delete[] gSyncMap2;
349     delete[] gTransformFeedbackMap;
350     delete[] gVertexArrayMap;
351 
352     for (uint8_t i = 0; i < gMaxContexts; i++)
353     {
354         delete[] gFramebufferMapPerContext[i];
355     }
356     delete[] gFramebufferMapPerContext;
357 }
358 
SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)359 void SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
360 {
361     gValidateSerializedStateCallback = callback;
362 }
363 
364 angle::TraceInfo gTraceInfo;
365 std::string gTraceGzPath;
366 
367 struct TraceFunctionsImpl : angle::TraceFunctions
368 {
SetupReplayTraceFunctionsImpl369     void SetupReplay() override { ::SetupReplay(); }
370 
ReplayFrameTraceFunctionsImpl371     void ReplayFrame(uint32_t frameIndex) override { ::ReplayFrame(frameIndex); }
372 
ResetReplayTraceFunctionsImpl373     void ResetReplay() override { ::ResetReplay(); }
374 
FinishReplayTraceFunctionsImpl375     void FinishReplay() override { ::FinishReplay(); }
376 
SetBinaryDataDirTraceFunctionsImpl377     void SetBinaryDataDir(const char *dataDir) override { gBinaryDataDir = dataDir; }
378 
SetReplayResourceModeTraceFunctionsImpl379     void SetReplayResourceMode(const angle::ReplayResourceMode resourceMode) override
380     {
381         gReplayResourceMode = resourceMode;
382     }
383 
SetTraceInfoTraceFunctionsImpl384     void SetTraceInfo(const angle::TraceInfo &traceInfo) override { gTraceInfo = traceInfo; }
385 
SetTraceGzPathTraceFunctionsImpl386     void SetTraceGzPath(const std::string &traceGzPath) override { gTraceGzPath = traceGzPath; }
387 };
388 
389 TraceFunctionsImpl gTraceFunctionsImpl;
390 
SetupEntryPoints(angle::TraceCallbacks * traceCallbacks,angle::TraceFunctions ** traceFunctions)391 void SetupEntryPoints(angle::TraceCallbacks *traceCallbacks, angle::TraceFunctions **traceFunctions)
392 {
393     gTraceCallbacks = traceCallbacks;
394     *traceFunctions = &gTraceFunctionsImpl;
395 }
396 
UpdateClientArrayPointer(int arrayIndex,const void * data,uint64_t size)397 void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
398 {
399     memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
400 }
401 BufferHandleMap gMappedBufferData;
402 
UpdateClientBufferData(GLuint bufferID,const void * source,GLsizei size)403 void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
404 {
405     memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
406 }
407 
UpdateClientBufferDataWithOffset(GLuint bufferID,const void * source,GLsizei size,GLsizei offset)408 void UpdateClientBufferDataWithOffset(GLuint bufferID,
409                                       const void *source,
410                                       GLsizei size,
411                                       GLsizei offset)
412 {
413     uintptr_t dest = reinterpret_cast<uintptr_t>(gMappedBufferData[gBufferMap[bufferID]]) + offset;
414     memcpy(reinterpret_cast<void *>(dest), source, size);
415 }
416 
UpdateResourceIDBuffer(int resourceIndex,GLuint id)417 void UpdateResourceIDBuffer(int resourceIndex, GLuint id)
418 {
419     gResourceIDBuffer[resourceIndex] = id;
420 }
421 
UpdateBufferID(GLuint id,GLsizei readBufferOffset)422 void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
423 {
424     UpdateResourceMap(gBufferMap, id, readBufferOffset);
425 }
426 
UpdateFenceNVID(GLuint id,GLsizei readBufferOffset)427 void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
428 {
429     UpdateResourceMap(gFenceNVMap, id, readBufferOffset);
430 }
431 
UpdateFramebufferID(GLuint id,GLsizei readBufferOffset)432 void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
433 {
434     UpdateResourceMap(gFramebufferMap, id, readBufferOffset);
435 }
436 
UpdateFramebufferID2(GLuint contextId,GLuint id,GLsizei readBufferOffset)437 void UpdateFramebufferID2(GLuint contextId, GLuint id, GLsizei readBufferOffset)
438 {
439     UpdateResourceMapPerContext(gFramebufferMapPerContext, contextId, id, readBufferOffset);
440 }
441 
UpdateMemoryObjectID(GLuint id,GLsizei readBufferOffset)442 void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
443 {
444     UpdateResourceMap(gMemoryObjectMap, id, readBufferOffset);
445 }
446 
UpdateProgramPipelineID(GLuint id,GLsizei readBufferOffset)447 void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
448 {
449     UpdateResourceMap(gProgramPipelineMap, id, readBufferOffset);
450 }
451 
UpdateQueryID(GLuint id,GLsizei readBufferOffset)452 void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
453 {
454     UpdateResourceMap(gQueryMap, id, readBufferOffset);
455 }
456 
UpdateRenderbufferID(GLuint id,GLsizei readBufferOffset)457 void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
458 {
459     UpdateResourceMap(gRenderbufferMap, id, readBufferOffset);
460 }
461 
UpdateSamplerID(GLuint id,GLsizei readBufferOffset)462 void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
463 {
464     UpdateResourceMap(gSamplerMap, id, readBufferOffset);
465 }
466 
UpdateSemaphoreID(GLuint id,GLsizei readBufferOffset)467 void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
468 {
469     UpdateResourceMap(gSemaphoreMap, id, readBufferOffset);
470 }
471 
UpdateShaderProgramID(GLuint id,GLsizei readBufferOffset)472 void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
473 {
474     UpdateResourceMap(gShaderProgramMap, id, readBufferOffset);
475 }
476 
UpdateTextureID(GLuint id,GLsizei readBufferOffset)477 void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
478 {
479     UpdateResourceMap(gTextureMap, id, readBufferOffset);
480 }
481 
UpdateTransformFeedbackID(GLuint id,GLsizei readBufferOffset)482 void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
483 {
484     UpdateResourceMap(gTransformFeedbackMap, id, readBufferOffset);
485 }
486 
UpdateVertexArrayID(GLuint id,GLsizei readBufferOffset)487 void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
488 {
489     UpdateResourceMap(gVertexArrayMap, id, readBufferOffset);
490 }
491 
SetFramebufferID(GLuint id)492 void SetFramebufferID(GLuint id)
493 {
494     glGenFramebuffers(1, &gFramebufferMap[id]);
495 }
496 
SetFramebufferID2(GLuint contextID,GLuint id)497 void SetFramebufferID2(GLuint contextID, GLuint id)
498 {
499     glGenFramebuffers(1, &gFramebufferMapPerContext[contextID][id]);
500 }
501 
SetBufferID(GLuint id)502 void SetBufferID(GLuint id)
503 {
504     glGenBuffers(1, &gBufferMap[id]);
505 }
506 
SetRenderbufferID(GLuint id)507 void SetRenderbufferID(GLuint id)
508 {
509     glGenRenderbuffers(1, &gRenderbufferMap[id]);
510 }
511 
SetTextureID(GLuint id)512 void SetTextureID(GLuint id)
513 {
514     glGenTextures(1, &gTextureMap[id]);
515 }
516 
ValidateSerializedState(const char * serializedState,const char * fileName,uint32_t line)517 void ValidateSerializedState(const char *serializedState, const char *fileName, uint32_t line)
518 {
519     if (gValidateSerializedStateCallback)
520     {
521         gValidateSerializedStateCallback(serializedState, fileName, line);
522     }
523 }
524 
MapBufferRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,GLuint buffer)525 void MapBufferRange(GLenum target,
526                     GLintptr offset,
527                     GLsizeiptr length,
528                     GLbitfield access,
529                     GLuint buffer)
530 {
531     gMappedBufferData[gBufferMap[buffer]] = glMapBufferRange(target, offset, length, access);
532 }
533 
MapBufferRangeEXT(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,GLuint buffer)534 void MapBufferRangeEXT(GLenum target,
535                        GLintptr offset,
536                        GLsizeiptr length,
537                        GLbitfield access,
538                        GLuint buffer)
539 {
540     gMappedBufferData[gBufferMap[buffer]] = glMapBufferRangeEXT(target, offset, length, access);
541 }
542 
MapBufferOES(GLenum target,GLbitfield access,GLuint buffer)543 void MapBufferOES(GLenum target, GLbitfield access, GLuint buffer)
544 {
545     gMappedBufferData[gBufferMap[buffer]] = glMapBufferOES(target, access);
546 }
547 
CreateShader(GLenum shaderType,GLuint shaderProgram)548 void CreateShader(GLenum shaderType, GLuint shaderProgram)
549 {
550     gShaderProgramMap[shaderProgram] = glCreateShader(shaderType);
551 }
552 
CreateProgram(GLuint shaderProgram)553 void CreateProgram(GLuint shaderProgram)
554 {
555     gShaderProgramMap[shaderProgram] = glCreateProgram();
556 }
557 
CreateShaderProgramv(GLenum type,GLsizei count,const GLchar * const * strings,GLuint shaderProgram)558 void CreateShaderProgramv(GLenum type,
559                           GLsizei count,
560                           const GLchar *const *strings,
561                           GLuint shaderProgram)
562 {
563     gShaderProgramMap[shaderProgram] = glCreateShaderProgramv(type, count, strings);
564 }
565 
FenceSync(GLenum condition,GLbitfield flags,uintptr_t fenceSync)566 void FenceSync(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
567 {
568     gSyncMap[fenceSync] = glFenceSync(condition, flags);
569 }
570 
FenceSync2(GLenum condition,GLbitfield flags,uintptr_t fenceSync)571 void FenceSync2(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
572 {
573     gSyncMap2[fenceSync] = glFenceSync(condition, flags);
574 }
575 
CreateEGLImageResource(GLsizei width,GLsizei height)576 GLuint CreateEGLImageResource(GLsizei width, GLsizei height)
577 {
578     GLint previousTexId;
579     glGetIntegerv(GL_TEXTURE_BINDING_2D, &previousTexId);
580     GLint previousAlignment;
581     glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment);
582 
583     // Create a texture and fill with a placeholder green value
584     GLuint stagingTexId;
585     glGenTextures(1, &stagingTexId);
586     glBindTexture(GL_TEXTURE_2D, stagingTexId);
587     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
588     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
589     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
590     std::vector<GLubyte> pixels;
591     pixels.reserve(width * height * 3);
592     for (int i = 0; i < width * height; i++)
593     {
594         pixels.push_back(61);
595         pixels.push_back(220);
596         pixels.push_back(132);
597     }
598     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,
599                  pixels.data());
600 
601     glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment);
602     glBindTexture(GL_TEXTURE_2D, previousTexId);
603     return stagingTexId;
604 }
605 
CreateEGLImage(EGLDisplay dpy,EGLContext ctx,EGLenum target,uintptr_t buffer,const EGLAttrib * attrib_list,GLsizei width,GLsizei height,GLuint imageID)606 void CreateEGLImage(EGLDisplay dpy,
607                     EGLContext ctx,
608                     EGLenum target,
609                     uintptr_t buffer,
610                     const EGLAttrib *attrib_list,
611                     GLsizei width,
612                     GLsizei height,
613                     GLuint imageID)
614 {
615     if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
616     {
617         // If this image was created from an AHB or the backing resource was not
618         // captured, create a new GL texture during replay to use instead.
619         // Substituting a GL texture for an AHB allows the trace to run on
620         // non-Android systems.
621         gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
622         gEGLImageMap2[imageID]          = eglCreateImage(
623             dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
624             reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
625     }
626     else
627     {
628         EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
629         gEGLImageMap2[imageID]       = eglCreateImage(dpy, ctx, target, clientBuffer, attrib_list);
630     }
631 }
632 
CreateEGLImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,uintptr_t buffer,const EGLint * attrib_list,GLsizei width,GLsizei height,GLuint imageID)633 void CreateEGLImageKHR(EGLDisplay dpy,
634                        EGLContext ctx,
635                        EGLenum target,
636                        uintptr_t buffer,
637                        const EGLint *attrib_list,
638                        GLsizei width,
639                        GLsizei height,
640                        GLuint imageID)
641 {
642     if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
643     {
644         gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
645         gEGLImageMap2[imageID]          = eglCreateImageKHR(
646             dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
647             reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
648     }
649     else
650     {
651         EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
652         gEGLImageMap2[imageID] = eglCreateImageKHR(dpy, ctx, target, clientBuffer, attrib_list);
653     }
654 }
655 
DestroyEGLImage(EGLDisplay dpy,EGLImage image,GLuint imageID)656 void DestroyEGLImage(EGLDisplay dpy, EGLImage image, GLuint imageID)
657 {
658     if (gEGLImageMap2Resources[imageID])
659     {
660         glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
661         gEGLImageMap2Resources[imageID] = 0;
662     }
663     eglDestroyImage(dpy, image);
664 }
665 
DestroyEGLImageKHR(EGLDisplay dpy,EGLImageKHR image,GLuint imageID)666 void DestroyEGLImageKHR(EGLDisplay dpy, EGLImageKHR image, GLuint imageID)
667 {
668     if (gEGLImageMap2Resources[imageID])
669     {
670         glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
671         gEGLImageMap2Resources[imageID] = 0;
672     }
673     eglDestroyImageKHR(dpy, image);
674 }
675 
CreateEGLSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list,GLuint syncID)676 void CreateEGLSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, GLuint syncID)
677 {
678     gEGLSyncMap[syncID] = eglCreateSyncKHR(dpy, type, attrib_list);
679 }
680 
CreateEGLSync(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list,GLuint syncID)681 void CreateEGLSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list, GLuint syncID)
682 {
683     gEGLSyncMap[syncID] = eglCreateSync(dpy, type, attrib_list);
684 }
685 
CreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list,GLuint surfaceID)686 void CreatePbufferSurface(EGLDisplay dpy,
687                           EGLConfig config,
688                           const EGLint *attrib_list,
689                           GLuint surfaceID)
690 {
691     gSurfaceMap2[surfaceID] = eglCreatePbufferSurface(dpy, config, attrib_list);
692 }
693 
CreateNativeClientBufferANDROID(const EGLint * attrib_list,uintptr_t clientBuffer)694 void CreateNativeClientBufferANDROID(const EGLint *attrib_list, uintptr_t clientBuffer)
695 {
696     gClientBufferMap[clientBuffer] = eglCreateNativeClientBufferANDROID(attrib_list);
697 }
698 
CreateContext(GLuint contextID)699 void CreateContext(GLuint contextID)
700 {
701     EGLContext shareContext = gContextMap2[gShareContextId];
702     EGLContext context      = eglCreateContext(nullptr, nullptr, shareContext, nullptr);
703     gContextMap2[contextID] = context;
704 }
705 
SetCurrentContextID(GLuint id)706 void SetCurrentContextID(GLuint id)
707 {
708     gContextMap2[id] = eglGetCurrentContext();
709 }
710 
711 ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEPROC r_eglCreateImage;
712 ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEKHRPROC r_eglCreateImageKHR;
713 ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEPROC r_eglDestroyImage;
714 ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEKHRPROC r_eglDestroyImageKHR;
715