• 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 DecompressCallback gDecompressCallback;
26 std::string gBinaryDataDir = ".";
27 
LoadBinaryData(const char * fileName)28 void LoadBinaryData(const char *fileName)
29 {
30     // TODO(b/179188489): Fix cross-module deallocation.
31     if (gBinaryData != nullptr)
32     {
33         delete[] gBinaryData;
34     }
35     char pathBuffer[1000] = {};
36 
37     sprintf(pathBuffer, "%s/%s", gBinaryDataDir.c_str(), fileName);
38     FILE *fp = fopen(pathBuffer, "rb");
39     if (fp == 0)
40     {
41         fprintf(stderr, "Error loading binary data file: %s\n", fileName);
42         return;
43     }
44     fseek(fp, 0, SEEK_END);
45     long size = ftell(fp);
46     fseek(fp, 0, SEEK_SET);
47     if (gDecompressCallback)
48     {
49         if (!strstr(fileName, ".gz"))
50         {
51             fprintf(stderr, "Filename does not end in .gz");
52             exit(1);
53         }
54         std::vector<uint8_t> compressedData(size);
55         (void)fread(compressedData.data(), 1, size, fp);
56         gBinaryData = gDecompressCallback(compressedData);
57     }
58     else
59     {
60         if (!strstr(fileName, ".angledata"))
61         {
62             fprintf(stderr, "Filename does not end in .angledata");
63             exit(1);
64         }
65         gBinaryData = new uint8_t[size];
66         (void)fread(gBinaryData, 1, size, fp);
67     }
68     fclose(fp);
69 }
70 
71 ValidateSerializedStateCallback gValidateSerializedStateCallback;
72 std::unordered_map<GLuint, std::vector<GLint>> gInternalUniformLocationsMap;
73 }  // namespace
74 
75 GLint **gUniformLocations;
76 BlockIndexesMap gUniformBlockIndexes;
77 GLuint gCurrentProgram = 0;
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     for (GLint arrayIndex = 0; arrayIndex < count; ++arrayIndex)
87     {
88         GLuint mappedProgramID = gShaderProgramMap[program];
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 }
UpdateCurrentProgram(GLuint program)104 void UpdateCurrentProgram(GLuint program)
105 {
106     gCurrentProgram = program;
107 }
108 
109 uint8_t *gBinaryData;
110 uint8_t *gReadBuffer;
111 uint8_t *gClientArrays[kMaxClientArrays];
112 SyncResourceMap gSyncMap;
113 ContextMap gContextMap;
114 
115 GLuint *gBufferMap;
116 GLuint *gFenceNVMap;
117 GLuint *gFramebufferMap;
118 GLuint *gMemoryObjectMap;
119 GLuint *gProgramPipelineMap;
120 GLuint *gQueryMap;
121 GLuint *gRenderbufferMap;
122 GLuint *gSamplerMap;
123 GLuint *gSemaphoreMap;
124 GLuint *gShaderProgramMap;
125 GLuint *gTextureMap;
126 GLuint *gTransformFeedbackMap;
127 GLuint *gVertexArrayMap;
128 
SetBinaryDataDecompressCallback(DecompressCallback callback)129 void SetBinaryDataDecompressCallback(DecompressCallback callback)
130 {
131     gDecompressCallback = callback;
132 }
133 
SetBinaryDataDir(const char * dataDir)134 void SetBinaryDataDir(const char *dataDir)
135 {
136     gBinaryDataDir = dataDir;
137 }
138 
AllocateZeroedUints(size_t count)139 GLuint *AllocateZeroedUints(size_t count)
140 {
141     GLuint *mem = new GLuint[count + 1];
142     memset(mem, 0, sizeof(GLuint) * (count + 1));
143     return mem;
144 }
145 
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)146 void InitializeReplay(const char *binaryDataFileName,
147                       size_t maxClientArraySize,
148                       size_t readBufferSize,
149                       uint32_t maxBuffer,
150                       uint32_t maxFenceNV,
151                       uint32_t maxFramebuffer,
152                       uint32_t maxMemoryObject,
153                       uint32_t maxProgramPipeline,
154                       uint32_t maxQuery,
155                       uint32_t maxRenderbuffer,
156                       uint32_t maxSampler,
157                       uint32_t maxSemaphore,
158                       uint32_t maxShaderProgram,
159                       uint32_t maxTexture,
160                       uint32_t maxTransformFeedback,
161                       uint32_t maxVertexArray)
162 {
163     LoadBinaryData(binaryDataFileName);
164 
165     for (uint8_t *&clientArray : gClientArrays)
166     {
167         clientArray = new uint8_t[maxClientArraySize];
168     }
169 
170     gReadBuffer = new uint8_t[readBufferSize];
171 
172     gBufferMap            = AllocateZeroedUints(maxBuffer);
173     gFenceNVMap           = AllocateZeroedUints(maxFenceNV);
174     gFramebufferMap       = AllocateZeroedUints(maxFramebuffer);
175     gMemoryObjectMap      = AllocateZeroedUints(maxMemoryObject);
176     gProgramPipelineMap   = AllocateZeroedUints(maxProgramPipeline);
177     gQueryMap             = AllocateZeroedUints(maxQuery);
178     gRenderbufferMap      = AllocateZeroedUints(maxRenderbuffer);
179     gSamplerMap           = AllocateZeroedUints(maxSampler);
180     gSemaphoreMap         = AllocateZeroedUints(maxSemaphore);
181     gShaderProgramMap     = AllocateZeroedUints(maxShaderProgram);
182     gTextureMap           = AllocateZeroedUints(maxTexture);
183     gTransformFeedbackMap = AllocateZeroedUints(maxTransformFeedback);
184     gVertexArrayMap       = AllocateZeroedUints(maxVertexArray);
185 
186     gUniformLocations = new GLint *[maxShaderProgram + 1];
187     memset(gUniformLocations, 0, sizeof(GLint *) * (maxShaderProgram + 1));
188 }
189 
FinishReplay()190 void FinishReplay()
191 {
192     for (uint8_t *&clientArray : gClientArrays)
193     {
194         delete[] clientArray;
195     }
196     delete[] gReadBuffer;
197 
198     delete[] gBufferMap;
199     delete[] gRenderbufferMap;
200     delete[] gTextureMap;
201     delete[] gFramebufferMap;
202     delete[] gShaderProgramMap;
203     delete[] gFenceNVMap;
204     delete[] gMemoryObjectMap;
205     delete[] gProgramPipelineMap;
206     delete[] gQueryMap;
207     delete[] gSamplerMap;
208     delete[] gSemaphoreMap;
209     delete[] gTransformFeedbackMap;
210     delete[] gVertexArrayMap;
211 }
212 
SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)213 void SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
214 {
215     gValidateSerializedStateCallback = callback;
216 }
217 
UpdateClientArrayPointer(int arrayIndex,const void * data,uint64_t size)218 void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
219 {
220     memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
221 }
222 BufferHandleMap gMappedBufferData;
223 
UpdateClientBufferData(GLuint bufferID,const void * source,GLsizei size)224 void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
225 {
226     memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
227 }
228 
UpdateClientBufferDataWithOffset(GLuint bufferID,const void * source,GLsizei size,GLsizei offset)229 void UpdateClientBufferDataWithOffset(GLuint bufferID,
230                                       const void *source,
231                                       GLsizei size,
232                                       GLsizei offset)
233 {
234     uintptr_t dest = reinterpret_cast<uintptr_t>(gMappedBufferData[gBufferMap[bufferID]]) + offset;
235     memcpy(reinterpret_cast<void *>(dest), source, size);
236 }
237 
UpdateBufferID(GLuint id,GLsizei readBufferOffset)238 void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
239 {
240     UpdateResourceMap(gBufferMap, id, readBufferOffset);
241 }
242 
UpdateFenceNVID(GLuint id,GLsizei readBufferOffset)243 void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
244 {
245     UpdateResourceMap(gFenceNVMap, id, readBufferOffset);
246 }
247 
UpdateFramebufferID(GLuint id,GLsizei readBufferOffset)248 void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
249 {
250     UpdateResourceMap(gFramebufferMap, id, readBufferOffset);
251 }
252 
UpdateMemoryObjectID(GLuint id,GLsizei readBufferOffset)253 void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
254 {
255     UpdateResourceMap(gMemoryObjectMap, id, readBufferOffset);
256 }
257 
UpdateProgramPipelineID(GLuint id,GLsizei readBufferOffset)258 void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
259 {
260     UpdateResourceMap(gProgramPipelineMap, id, readBufferOffset);
261 }
262 
UpdateQueryID(GLuint id,GLsizei readBufferOffset)263 void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
264 {
265     UpdateResourceMap(gQueryMap, id, readBufferOffset);
266 }
267 
UpdateRenderbufferID(GLuint id,GLsizei readBufferOffset)268 void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
269 {
270     UpdateResourceMap(gRenderbufferMap, id, readBufferOffset);
271 }
272 
UpdateSamplerID(GLuint id,GLsizei readBufferOffset)273 void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
274 {
275     UpdateResourceMap(gSamplerMap, id, readBufferOffset);
276 }
277 
UpdateSemaphoreID(GLuint id,GLsizei readBufferOffset)278 void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
279 {
280     UpdateResourceMap(gSemaphoreMap, id, readBufferOffset);
281 }
282 
UpdateShaderProgramID(GLuint id,GLsizei readBufferOffset)283 void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
284 {
285     UpdateResourceMap(gShaderProgramMap, id, readBufferOffset);
286 }
287 
UpdateTextureID(GLuint id,GLsizei readBufferOffset)288 void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
289 {
290     UpdateResourceMap(gTextureMap, id, readBufferOffset);
291 }
292 
UpdateTransformFeedbackID(GLuint id,GLsizei readBufferOffset)293 void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
294 {
295     UpdateResourceMap(gTransformFeedbackMap, id, readBufferOffset);
296 }
297 
UpdateVertexArrayID(GLuint id,GLsizei readBufferOffset)298 void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
299 {
300     UpdateResourceMap(gVertexArrayMap, id, readBufferOffset);
301 }
302 
SetResourceID(GLuint * map,GLuint id)303 void SetResourceID(GLuint *map, GLuint id)
304 {
305     if (map[id] != 0)
306     {
307         fprintf(stderr, "%s: resource ID %d is already reserved\n", __func__, id);
308         exit(1);
309     }
310     map[id] = id;
311 }
312 
SetFramebufferID(GLuint id)313 void SetFramebufferID(GLuint id)
314 {
315     SetResourceID(gFramebufferMap, id);
316 }
317 
SetBufferID(GLuint id)318 void SetBufferID(GLuint id)
319 {
320     SetResourceID(gBufferMap, id);
321 }
322 
SetRenderbufferID(GLuint id)323 void SetRenderbufferID(GLuint id)
324 {
325     SetResourceID(gRenderbufferMap, id);
326 }
327 
SetTextureID(GLuint id)328 void SetTextureID(GLuint id)
329 {
330     SetResourceID(gTextureMap, id);
331 }
332 
ValidateSerializedState(const char * serializedState,const char * fileName,uint32_t line)333 void ValidateSerializedState(const char *serializedState, const char *fileName, uint32_t line)
334 {
335     if (gValidateSerializedStateCallback)
336     {
337         gValidateSerializedStateCallback(serializedState, fileName, line);
338     }
339 }
340