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