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