• 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(ResourceMap * resourceMap,GLuint id,GLsizei readBufferOffset)18 void UpdateResourceMap(ResourceMap *resourceMap, GLuint id, GLsizei readBufferOffset)
19 {
20     GLuint returnedID;
21     memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
22     (*resourceMap)[id] = returnedID;
23 }
24 
UpdateResourceMap2(GLuint * resourceMap,GLuint id,GLsizei readBufferOffset)25 void UpdateResourceMap2(GLuint *resourceMap, GLuint id, GLsizei readBufferOffset)
26 {
27     GLuint returnedID;
28     memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
29     resourceMap[id] = returnedID;
30 }
31 
32 DecompressCallback gDecompressCallback;
33 std::string gBinaryDataDir = ".";
34 
LoadBinaryData(const char * fileName)35 void LoadBinaryData(const char *fileName)
36 {
37     // TODO(b/179188489): Fix cross-module deallocation.
38     if (gBinaryData != nullptr)
39     {
40         delete[] gBinaryData;
41     }
42     char pathBuffer[1000] = {};
43 
44     sprintf(pathBuffer, "%s/%s", gBinaryDataDir.c_str(), fileName);
45     FILE *fp = fopen(pathBuffer, "rb");
46     if (fp == 0)
47     {
48         fprintf(stderr, "Error loading binary data file: %s\n", fileName);
49         return;
50     }
51     fseek(fp, 0, SEEK_END);
52     long size = ftell(fp);
53     fseek(fp, 0, SEEK_SET);
54     if (gDecompressCallback)
55     {
56         if (!strstr(fileName, ".gz"))
57         {
58             fprintf(stderr, "Filename does not end in .gz");
59             exit(1);
60         }
61         std::vector<uint8_t> compressedData(size);
62         (void)fread(compressedData.data(), 1, size, fp);
63         gBinaryData = gDecompressCallback(compressedData);
64     }
65     else
66     {
67         if (!strstr(fileName, ".angledata"))
68         {
69             fprintf(stderr, "Filename does not end in .angledata");
70             exit(1);
71         }
72         gBinaryData = new uint8_t[size];
73         (void)fread(gBinaryData, 1, size, fp);
74     }
75     fclose(fp);
76 }
77 
78 ValidateSerializedStateCallback gValidateSerializedStateCallback;
79 std::unordered_map<GLuint, std::vector<GLint>> gInternalUniformLocationsMap;
80 }  // namespace
81 
82 LocationsMap gUniformLocations;
83 GLint **gUniformLocations2;
84 BlockIndexesMap gUniformBlockIndexes;
85 GLuint gCurrentProgram = 0;
86 
87 // TODO (http://anglebug.com/6234): Remove three parameter UpdateUniformLocation on next retrace
UpdateUniformLocation(GLuint program,const char * name,GLint location)88 void UpdateUniformLocation(GLuint program, const char *name, GLint location)
89 {
90     gUniformLocations[program][location] = glGetUniformLocation(program, name);
91 }
92 
UpdateUniformLocation(GLuint program,const char * name,GLint location,GLint count)93 void UpdateUniformLocation(GLuint program, const char *name, GLint location, GLint count)
94 {
95     for (GLint i = 0; i < count; i++)
96     {
97         gUniformLocations[program][location + i] = glGetUniformLocation(program, name) + i;
98     }
99 }
100 
UpdateUniformLocation2(GLuint program,const char * name,GLint location,GLint count)101 void UpdateUniformLocation2(GLuint program, const char *name, GLint location, GLint count)
102 {
103     std::vector<GLint> &programLocations = gInternalUniformLocationsMap[program];
104     if (static_cast<GLint>(programLocations.size()) < location + count)
105     {
106         programLocations.resize(location + count, 0);
107     }
108     for (GLint arrayIndex = 0; arrayIndex < count; ++arrayIndex)
109     {
110         programLocations[location + arrayIndex] = glGetUniformLocation(program, name) + arrayIndex;
111     }
112     gUniformLocations2[program] = programLocations.data();
113 }
114 
DeleteUniformLocations(GLuint program)115 void DeleteUniformLocations(GLuint program)
116 {
117     gUniformLocations.erase(program);
118 }
119 
DeleteUniformLocations2(GLuint program)120 void DeleteUniformLocations2(GLuint program)
121 {
122     // No-op. We leave uniform locations around so deleted current programs can still use them.
123 }
124 
UpdateUniformBlockIndex(GLuint program,const char * name,GLuint index)125 void UpdateUniformBlockIndex(GLuint program, const char *name, GLuint index)
126 {
127     gUniformBlockIndexes[program][index] = glGetUniformBlockIndex(program, name);
128 }
UpdateCurrentProgram(GLuint program)129 void UpdateCurrentProgram(GLuint program)
130 {
131     gCurrentProgram = program;
132 }
133 
134 uint8_t *gBinaryData;
135 uint8_t *gReadBuffer;
136 uint8_t *gClientArrays[kMaxClientArrays];
137 ResourceMap gBufferMap;
138 ResourceMap gFenceNVMap;
139 ResourceMap gFramebufferMap;
140 ResourceMap gMemoryObjectMap;
141 ResourceMap gProgramPipelineMap;
142 ResourceMap gQueryMap;
143 ResourceMap gRenderbufferMap;
144 ResourceMap gSamplerMap;
145 ResourceMap gSemaphoreMap;
146 ResourceMap gShaderProgramMap;
147 ResourceMap gTextureMap;
148 ResourceMap gTransformFeedbackMap;
149 ResourceMap gVertexArrayMap;
150 SyncResourceMap gSyncMap;
151 ContextMap gContextMap;
152 
153 GLuint *gBufferMap2;
154 GLuint *gFenceNVMap2;
155 GLuint *gFramebufferMap2;
156 GLuint *gMemoryObjectMap2;
157 GLuint *gProgramPipelineMap2;
158 GLuint *gQueryMap2;
159 GLuint *gRenderbufferMap2;
160 GLuint *gSamplerMap2;
161 GLuint *gSemaphoreMap2;
162 GLuint *gShaderProgramMap2;
163 GLuint *gTextureMap2;
164 GLuint *gTransformFeedbackMap2;
165 GLuint *gVertexArrayMap2;
166 
SetBinaryDataDecompressCallback(DecompressCallback callback)167 void SetBinaryDataDecompressCallback(DecompressCallback callback)
168 {
169     gDecompressCallback = callback;
170 }
171 
SetBinaryDataDir(const char * dataDir)172 void SetBinaryDataDir(const char *dataDir)
173 {
174     gBinaryDataDir = dataDir;
175 }
176 
InitializeReplay(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize)177 void InitializeReplay(const char *binaryDataFileName,
178                       size_t maxClientArraySize,
179                       size_t readBufferSize)
180 {
181     LoadBinaryData(binaryDataFileName);
182 
183     for (uint8_t *&clientArray : gClientArrays)
184     {
185         clientArray = new uint8_t[maxClientArraySize];
186     }
187 
188     gReadBuffer = new uint8_t[readBufferSize];
189 }
190 
AllocateZeroedUints(size_t count)191 GLuint *AllocateZeroedUints(size_t count)
192 {
193     GLuint *mem = new GLuint[count + 1];
194     memset(mem, 0, sizeof(GLuint) * (count + 1));
195     return mem;
196 }
197 
InitializeReplay2(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)198 void InitializeReplay2(const char *binaryDataFileName,
199                        size_t maxClientArraySize,
200                        size_t readBufferSize,
201                        uint32_t maxBuffer,
202                        uint32_t maxFenceNV,
203                        uint32_t maxFramebuffer,
204                        uint32_t maxMemoryObject,
205                        uint32_t maxProgramPipeline,
206                        uint32_t maxQuery,
207                        uint32_t maxRenderbuffer,
208                        uint32_t maxSampler,
209                        uint32_t maxSemaphore,
210                        uint32_t maxShaderProgram,
211                        uint32_t maxTexture,
212                        uint32_t maxTransformFeedback,
213                        uint32_t maxVertexArray)
214 {
215     InitializeReplay(binaryDataFileName, maxClientArraySize, readBufferSize);
216 
217     gBufferMap2            = AllocateZeroedUints(maxBuffer);
218     gFenceNVMap2           = AllocateZeroedUints(maxFenceNV);
219     gFramebufferMap2       = AllocateZeroedUints(maxFramebuffer);
220     gMemoryObjectMap2      = AllocateZeroedUints(maxMemoryObject);
221     gProgramPipelineMap2   = AllocateZeroedUints(maxProgramPipeline);
222     gQueryMap2             = AllocateZeroedUints(maxQuery);
223     gRenderbufferMap2      = AllocateZeroedUints(maxRenderbuffer);
224     gSamplerMap2           = AllocateZeroedUints(maxSampler);
225     gSemaphoreMap2         = AllocateZeroedUints(maxSemaphore);
226     gShaderProgramMap2     = AllocateZeroedUints(maxShaderProgram);
227     gTextureMap2           = AllocateZeroedUints(maxTexture);
228     gTransformFeedbackMap2 = AllocateZeroedUints(maxTransformFeedback);
229     gVertexArrayMap2       = AllocateZeroedUints(maxVertexArray);
230 
231     gUniformLocations2 = new GLint *[maxShaderProgram + 1];
232     memset(gUniformLocations2, 0, sizeof(GLint *) * (maxShaderProgram + 1));
233 }
234 
FinishReplay()235 void FinishReplay()
236 {
237     for (uint8_t *&clientArray : gClientArrays)
238     {
239         delete[] clientArray;
240     }
241     delete[] gReadBuffer;
242 
243     delete[] gBufferMap2;
244     delete[] gRenderbufferMap2;
245     delete[] gTextureMap2;
246     delete[] gFramebufferMap2;
247     delete[] gShaderProgramMap2;
248     delete[] gFenceNVMap2;
249     delete[] gMemoryObjectMap2;
250     delete[] gProgramPipelineMap2;
251     delete[] gQueryMap2;
252     delete[] gSamplerMap2;
253     delete[] gSemaphoreMap2;
254     delete[] gTransformFeedbackMap2;
255     delete[] gVertexArrayMap2;
256 }
257 
SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)258 void SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
259 {
260     gValidateSerializedStateCallback = callback;
261 }
262 
UpdateClientArrayPointer(int arrayIndex,const void * data,uint64_t size)263 void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
264 {
265     memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
266 }
267 BufferHandleMap gMappedBufferData;
268 
UpdateClientBufferData(GLuint bufferID,const void * source,GLsizei size)269 void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
270 {
271     memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
272 }
273 
UpdateClientBufferData2(GLuint bufferID,const void * source,GLsizei size)274 void UpdateClientBufferData2(GLuint bufferID, const void *source, GLsizei size)
275 {
276     memcpy(gMappedBufferData[gBufferMap2[bufferID]], source, size);
277 }
278 
UpdateClientBufferData2WithOffset(GLuint bufferID,const void * source,GLsizei size,GLsizei offset)279 void UpdateClientBufferData2WithOffset(GLuint bufferID,
280                                        const void *source,
281                                        GLsizei size,
282                                        GLsizei offset)
283 {
284     uintptr_t dest = reinterpret_cast<uintptr_t>(gMappedBufferData[gBufferMap2[bufferID]]) + offset;
285     memcpy(reinterpret_cast<void *>(dest), source, size);
286 }
287 
UpdateBufferID(GLuint id,GLsizei readBufferOffset)288 void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
289 {
290     UpdateResourceMap(&gBufferMap, id, readBufferOffset);
291 }
292 
UpdateFenceNVID(GLuint id,GLsizei readBufferOffset)293 void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
294 {
295     UpdateResourceMap(&gFenceNVMap, id, readBufferOffset);
296 }
297 
UpdateFramebufferID(GLuint id,GLsizei readBufferOffset)298 void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
299 {
300     UpdateResourceMap(&gFramebufferMap, id, readBufferOffset);
301 }
302 
UpdateMemoryObjectID(GLuint id,GLsizei readBufferOffset)303 void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
304 {
305     UpdateResourceMap(&gMemoryObjectMap, id, readBufferOffset);
306 }
307 
UpdateProgramPipelineID(GLuint id,GLsizei readBufferOffset)308 void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
309 {
310     UpdateResourceMap(&gProgramPipelineMap, id, readBufferOffset);
311 }
312 
UpdateQueryID(GLuint id,GLsizei readBufferOffset)313 void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
314 {
315     UpdateResourceMap(&gQueryMap, id, readBufferOffset);
316 }
317 
UpdateRenderbufferID(GLuint id,GLsizei readBufferOffset)318 void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
319 {
320     UpdateResourceMap(&gRenderbufferMap, id, readBufferOffset);
321 }
322 
UpdateSamplerID(GLuint id,GLsizei readBufferOffset)323 void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
324 {
325     UpdateResourceMap(&gSamplerMap, id, readBufferOffset);
326 }
327 
UpdateSemaphoreID(GLuint id,GLsizei readBufferOffset)328 void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
329 {
330     UpdateResourceMap(&gSemaphoreMap, id, readBufferOffset);
331 }
332 
UpdateShaderProgramID(GLuint id,GLsizei readBufferOffset)333 void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
334 {
335     UpdateResourceMap(&gShaderProgramMap, id, readBufferOffset);
336 }
337 
UpdateTextureID(GLuint id,GLsizei readBufferOffset)338 void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
339 {
340     UpdateResourceMap(&gTextureMap, id, readBufferOffset);
341 }
342 
UpdateTransformFeedbackID(GLuint id,GLsizei readBufferOffset)343 void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
344 {
345     UpdateResourceMap(&gTransformFeedbackMap, id, readBufferOffset);
346 }
347 
UpdateVertexArrayID(GLuint id,GLsizei readBufferOffset)348 void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
349 {
350     UpdateResourceMap(&gVertexArrayMap, id, readBufferOffset);
351 }
352 
UpdateBufferID2(GLuint id,GLsizei readBufferOffset)353 void UpdateBufferID2(GLuint id, GLsizei readBufferOffset)
354 {
355     UpdateResourceMap2(gBufferMap2, id, readBufferOffset);
356 }
357 
UpdateFenceNVID2(GLuint id,GLsizei readBufferOffset)358 void UpdateFenceNVID2(GLuint id, GLsizei readBufferOffset)
359 {
360     UpdateResourceMap2(gFenceNVMap2, id, readBufferOffset);
361 }
362 
UpdateFramebufferID2(GLuint id,GLsizei readBufferOffset)363 void UpdateFramebufferID2(GLuint id, GLsizei readBufferOffset)
364 {
365     UpdateResourceMap2(gFramebufferMap2, id, readBufferOffset);
366 }
367 
UpdateMemoryObjectID2(GLuint id,GLsizei readBufferOffset)368 void UpdateMemoryObjectID2(GLuint id, GLsizei readBufferOffset)
369 {
370     UpdateResourceMap2(gMemoryObjectMap2, id, readBufferOffset);
371 }
372 
UpdateProgramPipelineID2(GLuint id,GLsizei readBufferOffset)373 void UpdateProgramPipelineID2(GLuint id, GLsizei readBufferOffset)
374 {
375     UpdateResourceMap2(gProgramPipelineMap2, id, readBufferOffset);
376 }
377 
UpdateQueryID2(GLuint id,GLsizei readBufferOffset)378 void UpdateQueryID2(GLuint id, GLsizei readBufferOffset)
379 {
380     UpdateResourceMap2(gQueryMap2, id, readBufferOffset);
381 }
382 
UpdateRenderbufferID2(GLuint id,GLsizei readBufferOffset)383 void UpdateRenderbufferID2(GLuint id, GLsizei readBufferOffset)
384 {
385     UpdateResourceMap2(gRenderbufferMap2, id, readBufferOffset);
386 }
387 
UpdateSamplerID2(GLuint id,GLsizei readBufferOffset)388 void UpdateSamplerID2(GLuint id, GLsizei readBufferOffset)
389 {
390     UpdateResourceMap2(gSamplerMap2, id, readBufferOffset);
391 }
392 
UpdateSemaphoreID2(GLuint id,GLsizei readBufferOffset)393 void UpdateSemaphoreID2(GLuint id, GLsizei readBufferOffset)
394 {
395     UpdateResourceMap2(gSemaphoreMap2, id, readBufferOffset);
396 }
397 
UpdateShaderProgramID2(GLuint id,GLsizei readBufferOffset)398 void UpdateShaderProgramID2(GLuint id, GLsizei readBufferOffset)
399 {
400     UpdateResourceMap2(gShaderProgramMap2, id, readBufferOffset);
401 }
402 
UpdateTextureID2(GLuint id,GLsizei readBufferOffset)403 void UpdateTextureID2(GLuint id, GLsizei readBufferOffset)
404 {
405     UpdateResourceMap2(gTextureMap2, id, readBufferOffset);
406 }
407 
UpdateTransformFeedbackID2(GLuint id,GLsizei readBufferOffset)408 void UpdateTransformFeedbackID2(GLuint id, GLsizei readBufferOffset)
409 {
410     UpdateResourceMap2(gTransformFeedbackMap2, id, readBufferOffset);
411 }
412 
UpdateVertexArrayID2(GLuint id,GLsizei readBufferOffset)413 void UpdateVertexArrayID2(GLuint id, GLsizei readBufferOffset)
414 {
415     UpdateResourceMap2(gVertexArrayMap2, id, readBufferOffset);
416 }
417 
SetResourceID(GLuint * map,GLuint id)418 void SetResourceID(GLuint *map, GLuint id)
419 {
420     if (map[id] != 0)
421     {
422         fprintf(stderr, "%s: resource ID %d is already reserved\n", __func__, id);
423         exit(1);
424     }
425     map[id] = id;
426 }
427 
SetFramebufferID(GLuint id)428 void SetFramebufferID(GLuint id)
429 {
430     SetResourceID(gFramebufferMap2, id);
431 }
432 
ValidateSerializedState(const char * serializedState,const char * fileName,uint32_t line)433 void ValidateSerializedState(const char *serializedState, const char *fileName, uint32_t line)
434 {
435     if (gValidateSerializedStateCallback)
436     {
437         gValidateSerializedStateCallback(serializedState, fileName, line);
438     }
439 }
440