• 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 
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     delete[] gReadBuffer;
328     for (uint8_t *&clientArray : gClientArrays)
329     {
330         delete[] clientArray;
331     }
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 
SetupFirstFrameTraceFunctionsImpl375     void SetupFirstFrame() override {}
376 
FinishReplayTraceFunctionsImpl377     void FinishReplay() override { ::FinishReplay(); }
378 
SetBinaryDataDirTraceFunctionsImpl379     void SetBinaryDataDir(const char *dataDir) override { gBinaryDataDir = dataDir; }
380 
SetReplayResourceModeTraceFunctionsImpl381     void SetReplayResourceMode(const angle::ReplayResourceMode resourceMode) override
382     {
383         gReplayResourceMode = resourceMode;
384     }
385 
SetTraceInfoTraceFunctionsImpl386     void SetTraceInfo(const angle::TraceInfo &traceInfo) override { gTraceInfo = traceInfo; }
387 
SetTraceGzPathTraceFunctionsImpl388     void SetTraceGzPath(const std::string &traceGzPath) override { gTraceGzPath = traceGzPath; }
389 };
390 
391 TraceFunctionsImpl gTraceFunctionsImpl;
392 
SetupEntryPoints(angle::TraceCallbacks * traceCallbacks,angle::TraceFunctions ** traceFunctions)393 void SetupEntryPoints(angle::TraceCallbacks *traceCallbacks, angle::TraceFunctions **traceFunctions)
394 {
395     gTraceCallbacks = traceCallbacks;
396     *traceFunctions = &gTraceFunctionsImpl;
397 }
398 
UpdateClientArrayPointer(int arrayIndex,const void * data,uint64_t size)399 void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
400 {
401     memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
402 }
403 BufferHandleMap gMappedBufferData;
404 
UpdateClientBufferData(GLuint bufferID,const void * source,GLsizei size)405 void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
406 {
407     memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
408 }
409 
UpdateClientBufferDataWithOffset(GLuint bufferID,const void * source,GLsizei size,GLsizei offset)410 void UpdateClientBufferDataWithOffset(GLuint bufferID,
411                                       const void *source,
412                                       GLsizei size,
413                                       GLsizei offset)
414 {
415     uintptr_t dest = reinterpret_cast<uintptr_t>(gMappedBufferData[gBufferMap[bufferID]]) + offset;
416     memcpy(reinterpret_cast<void *>(dest), source, size);
417 }
418 
UpdateResourceIDBuffer(int resourceIndex,GLuint id)419 void UpdateResourceIDBuffer(int resourceIndex, GLuint id)
420 {
421     gResourceIDBuffer[resourceIndex] = id;
422 }
423 
UpdateBufferID(GLuint id,GLsizei readBufferOffset)424 void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
425 {
426     UpdateResourceMap(gBufferMap, id, readBufferOffset);
427 }
428 
UpdateFenceNVID(GLuint id,GLsizei readBufferOffset)429 void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
430 {
431     UpdateResourceMap(gFenceNVMap, id, readBufferOffset);
432 }
433 
UpdateFramebufferID(GLuint id,GLsizei readBufferOffset)434 void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
435 {
436     UpdateResourceMap(gFramebufferMap, id, readBufferOffset);
437 }
438 
UpdateFramebufferID2(GLuint contextId,GLuint id,GLsizei readBufferOffset)439 void UpdateFramebufferID2(GLuint contextId, GLuint id, GLsizei readBufferOffset)
440 {
441     UpdateResourceMapPerContext(gFramebufferMapPerContext, contextId, id, readBufferOffset);
442 }
443 
UpdateMemoryObjectID(GLuint id,GLsizei readBufferOffset)444 void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
445 {
446     UpdateResourceMap(gMemoryObjectMap, id, readBufferOffset);
447 }
448 
UpdateProgramPipelineID(GLuint id,GLsizei readBufferOffset)449 void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
450 {
451     UpdateResourceMap(gProgramPipelineMap, id, readBufferOffset);
452 }
453 
UpdateQueryID(GLuint id,GLsizei readBufferOffset)454 void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
455 {
456     UpdateResourceMap(gQueryMap, id, readBufferOffset);
457 }
458 
UpdateRenderbufferID(GLuint id,GLsizei readBufferOffset)459 void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
460 {
461     UpdateResourceMap(gRenderbufferMap, id, readBufferOffset);
462 }
463 
UpdateSamplerID(GLuint id,GLsizei readBufferOffset)464 void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
465 {
466     UpdateResourceMap(gSamplerMap, id, readBufferOffset);
467 }
468 
UpdateSemaphoreID(GLuint id,GLsizei readBufferOffset)469 void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
470 {
471     UpdateResourceMap(gSemaphoreMap, id, readBufferOffset);
472 }
473 
UpdateShaderProgramID(GLuint id,GLsizei readBufferOffset)474 void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
475 {
476     UpdateResourceMap(gShaderProgramMap, id, readBufferOffset);
477 }
478 
UpdateTextureID(GLuint id,GLsizei readBufferOffset)479 void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
480 {
481     UpdateResourceMap(gTextureMap, id, readBufferOffset);
482 }
483 
UpdateTransformFeedbackID(GLuint id,GLsizei readBufferOffset)484 void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
485 {
486     UpdateResourceMap(gTransformFeedbackMap, id, readBufferOffset);
487 }
488 
UpdateVertexArrayID(GLuint id,GLsizei readBufferOffset)489 void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
490 {
491     UpdateResourceMap(gVertexArrayMap, id, readBufferOffset);
492 }
493 
SetFramebufferID(GLuint id)494 void SetFramebufferID(GLuint id)
495 {
496     glGenFramebuffers(1, &gFramebufferMap[id]);
497 }
498 
SetFramebufferID2(GLuint contextID,GLuint id)499 void SetFramebufferID2(GLuint contextID, GLuint id)
500 {
501     glGenFramebuffers(1, &gFramebufferMapPerContext[contextID][id]);
502 }
503 
SetBufferID(GLuint id)504 void SetBufferID(GLuint id)
505 {
506     glGenBuffers(1, &gBufferMap[id]);
507 }
508 
SetRenderbufferID(GLuint id)509 void SetRenderbufferID(GLuint id)
510 {
511     glGenRenderbuffers(1, &gRenderbufferMap[id]);
512 }
513 
SetTextureID(GLuint id)514 void SetTextureID(GLuint id)
515 {
516     glGenTextures(1, &gTextureMap[id]);
517 }
518 
ValidateSerializedState(const char * serializedState,const char * fileName,uint32_t line)519 void ValidateSerializedState(const char *serializedState, const char *fileName, uint32_t line)
520 {
521     if (gValidateSerializedStateCallback)
522     {
523         gValidateSerializedStateCallback(serializedState, fileName, line);
524     }
525 }
526 
MapBufferRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,GLuint buffer)527 void MapBufferRange(GLenum target,
528                     GLintptr offset,
529                     GLsizeiptr length,
530                     GLbitfield access,
531                     GLuint buffer)
532 {
533     gMappedBufferData[gBufferMap[buffer]] = glMapBufferRange(target, offset, length, access);
534 }
535 
MapBufferRangeEXT(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,GLuint buffer)536 void MapBufferRangeEXT(GLenum target,
537                        GLintptr offset,
538                        GLsizeiptr length,
539                        GLbitfield access,
540                        GLuint buffer)
541 {
542     gMappedBufferData[gBufferMap[buffer]] = glMapBufferRangeEXT(target, offset, length, access);
543 }
544 
MapBufferOES(GLenum target,GLbitfield access,GLuint buffer)545 void MapBufferOES(GLenum target, GLbitfield access, GLuint buffer)
546 {
547     gMappedBufferData[gBufferMap[buffer]] = glMapBufferOES(target, access);
548 }
549 
CreateShader(GLenum shaderType,GLuint shaderProgram)550 void CreateShader(GLenum shaderType, GLuint shaderProgram)
551 {
552     gShaderProgramMap[shaderProgram] = glCreateShader(shaderType);
553 }
554 
CreateProgram(GLuint shaderProgram)555 void CreateProgram(GLuint shaderProgram)
556 {
557     gShaderProgramMap[shaderProgram] = glCreateProgram();
558 }
559 
CreateShaderProgramv(GLenum type,GLsizei count,const GLchar * const * strings,GLuint shaderProgram)560 void CreateShaderProgramv(GLenum type,
561                           GLsizei count,
562                           const GLchar *const *strings,
563                           GLuint shaderProgram)
564 {
565     gShaderProgramMap[shaderProgram] = glCreateShaderProgramv(type, count, strings);
566 }
567 
FenceSync(GLenum condition,GLbitfield flags,uintptr_t fenceSync)568 void FenceSync(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
569 {
570     gSyncMap[fenceSync] = glFenceSync(condition, flags);
571 }
572 
FenceSync2(GLenum condition,GLbitfield flags,uintptr_t fenceSync)573 void FenceSync2(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
574 {
575     gSyncMap2[fenceSync] = glFenceSync(condition, flags);
576 }
577 
CreateEGLImageResource(GLsizei width,GLsizei height)578 GLuint CreateEGLImageResource(GLsizei width, GLsizei height)
579 {
580     GLint previousTexId;
581     glGetIntegerv(GL_TEXTURE_BINDING_2D, &previousTexId);
582     GLint previousAlignment;
583     glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment);
584 
585     // Create a texture and fill with a placeholder green value
586     GLuint stagingTexId;
587     glGenTextures(1, &stagingTexId);
588     glBindTexture(GL_TEXTURE_2D, stagingTexId);
589     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
590     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
591     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
592     std::vector<GLubyte> pixels;
593     pixels.reserve(width * height * 3);
594     for (int i = 0; i < width * height; i++)
595     {
596         pixels.push_back(61);
597         pixels.push_back(220);
598         pixels.push_back(132);
599     }
600     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,
601                  pixels.data());
602 
603     glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment);
604     glBindTexture(GL_TEXTURE_2D, previousTexId);
605     return stagingTexId;
606 }
607 
CreateEGLImage(EGLDisplay dpy,EGLContext ctx,EGLenum target,uintptr_t buffer,const EGLAttrib * attrib_list,GLsizei width,GLsizei height,GLuint imageID)608 void CreateEGLImage(EGLDisplay dpy,
609                     EGLContext ctx,
610                     EGLenum target,
611                     uintptr_t buffer,
612                     const EGLAttrib *attrib_list,
613                     GLsizei width,
614                     GLsizei height,
615                     GLuint imageID)
616 {
617     if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
618     {
619         // If this image was created from an AHB or the backing resource was not
620         // captured, create a new GL texture during replay to use instead.
621         // Substituting a GL texture for an AHB allows the trace to run on
622         // non-Android systems.
623         gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
624         gEGLImageMap2[imageID]          = eglCreateImage(
625             dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
626             reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
627     }
628     else
629     {
630         EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
631         gEGLImageMap2[imageID]       = eglCreateImage(dpy, ctx, target, clientBuffer, attrib_list);
632     }
633 }
634 
CreateEGLImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,uintptr_t buffer,const EGLint * attrib_list,GLsizei width,GLsizei height,GLuint imageID)635 void CreateEGLImageKHR(EGLDisplay dpy,
636                        EGLContext ctx,
637                        EGLenum target,
638                        uintptr_t buffer,
639                        const EGLint *attrib_list,
640                        GLsizei width,
641                        GLsizei height,
642                        GLuint imageID)
643 {
644     if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
645     {
646         gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
647         gEGLImageMap2[imageID]          = eglCreateImageKHR(
648             dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
649             reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
650     }
651     else
652     {
653         EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
654         gEGLImageMap2[imageID] = eglCreateImageKHR(dpy, ctx, target, clientBuffer, attrib_list);
655     }
656 }
657 
DestroyEGLImage(EGLDisplay dpy,EGLImage image,GLuint imageID)658 void DestroyEGLImage(EGLDisplay dpy, EGLImage image, GLuint imageID)
659 {
660     if (gEGLImageMap2Resources[imageID])
661     {
662         glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
663         gEGLImageMap2Resources[imageID] = 0;
664     }
665     eglDestroyImage(dpy, image);
666 }
667 
DestroyEGLImageKHR(EGLDisplay dpy,EGLImageKHR image,GLuint imageID)668 void DestroyEGLImageKHR(EGLDisplay dpy, EGLImageKHR image, GLuint imageID)
669 {
670     if (gEGLImageMap2Resources[imageID])
671     {
672         glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
673         gEGLImageMap2Resources[imageID] = 0;
674     }
675     eglDestroyImageKHR(dpy, image);
676 }
677 
CreateEGLSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list,GLuint syncID)678 void CreateEGLSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, GLuint syncID)
679 {
680     gEGLSyncMap[syncID] = eglCreateSyncKHR(dpy, type, attrib_list);
681 }
682 
CreateEGLSync(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list,GLuint syncID)683 void CreateEGLSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list, GLuint syncID)
684 {
685     gEGLSyncMap[syncID] = eglCreateSync(dpy, type, attrib_list);
686 }
687 
CreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list,GLuint surfaceID)688 void CreatePbufferSurface(EGLDisplay dpy,
689                           EGLConfig config,
690                           const EGLint *attrib_list,
691                           GLuint surfaceID)
692 {
693     gSurfaceMap2[surfaceID] = eglCreatePbufferSurface(dpy, config, attrib_list);
694 }
695 
CreateNativeClientBufferANDROID(const EGLint * attrib_list,uintptr_t clientBuffer)696 void CreateNativeClientBufferANDROID(const EGLint *attrib_list, uintptr_t clientBuffer)
697 {
698     gClientBufferMap[clientBuffer] = eglCreateNativeClientBufferANDROID(attrib_list);
699 }
700 
CreateContext(GLuint contextID)701 void CreateContext(GLuint contextID)
702 {
703     EGLContext shareContext = gContextMap2[gShareContextId];
704     EGLContext context      = eglCreateContext(nullptr, nullptr, shareContext, nullptr);
705     gContextMap2[contextID] = context;
706 }
707 
SetCurrentContextID(GLuint id)708 void SetCurrentContextID(GLuint id)
709 {
710     gContextMap2[id] = eglGetCurrentContext();
711 }
712 
713 ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEPROC r_eglCreateImage;
714 ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEKHRPROC r_eglCreateImageKHR;
715 ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEPROC r_eglDestroyImage;
716 ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEKHRPROC r_eglDestroyImageKHR;
717