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 namespace
15 {
UpdateResourceMap(ResourceMap * resourceMap,GLuint id,GLsizei readBufferOffset)16 void UpdateResourceMap(ResourceMap *resourceMap, GLuint id, GLsizei readBufferOffset)
17 {
18     GLuint returnedID;
19     memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
20     (*resourceMap)[id] = returnedID;
21 }
22 
23 DecompressCallback gDecompressCallback;
24 const char *gBinaryDataDir = ".";
25 
LoadBinaryData(const char * fileName)26 void LoadBinaryData(const char *fileName)
27 {
28     // TODO(b/179188489): Fix cross-module deallocation.
29     if (gBinaryData != nullptr)
30     {
31         delete[] gBinaryData;
32     }
33     char pathBuffer[1000] = {};
34     sprintf(pathBuffer, "%s/%s", gBinaryDataDir, fileName);
35     FILE *fp = fopen(pathBuffer, "rb");
36     if (fp == 0)
37     {
38         fprintf(stderr, "Error loading binary data file: %s\n", fileName);
39         return;
40     }
41     fseek(fp, 0, SEEK_END);
42     long size = ftell(fp);
43     fseek(fp, 0, SEEK_SET);
44     if (gDecompressCallback)
45     {
46         if (!strstr(fileName, ".gz"))
47         {
48             fprintf(stderr, "Filename does not end in .gz");
49             exit(1);
50         }
51         std::vector<uint8_t> compressedData(size);
52         (void)fread(compressedData.data(), 1, size, fp);
53         gBinaryData = gDecompressCallback(compressedData);
54     }
55     else
56     {
57         if (!strstr(fileName, ".angledata"))
58         {
59             fprintf(stderr, "Filename does not end in .angledata");
60             exit(1);
61         }
62         gBinaryData = new uint8_t[size];
63         (void)fread(gBinaryData, 1, size, fp);
64     }
65     fclose(fp);
66 }
67 }  // namespace
68 
69 LocationsMap gUniformLocations;
70 BlockIndexesMap gUniformBlockIndexes;
71 GLuint gCurrentProgram = 0;
72 
UpdateUniformLocation(GLuint program,const char * name,GLint location)73 void UpdateUniformLocation(GLuint program, const char *name, GLint location)
74 {
75     gUniformLocations[program][location] = glGetUniformLocation(program, name);
76 }
DeleteUniformLocations(GLuint program)77 void DeleteUniformLocations(GLuint program)
78 {
79     gUniformLocations.erase(program);
80 }
UpdateUniformBlockIndex(GLuint program,const char * name,GLuint index)81 void UpdateUniformBlockIndex(GLuint program, const char *name, GLuint index)
82 {
83     gUniformBlockIndexes[program][index] = glGetUniformBlockIndex(program, name);
84 }
UpdateCurrentProgram(GLuint program)85 void UpdateCurrentProgram(GLuint program)
86 {
87     gCurrentProgram = program;
88 }
89 
90 uint8_t *gBinaryData;
91 uint8_t *gReadBuffer;
92 uint8_t *gClientArrays[kMaxClientArrays];
93 ResourceMap gBufferMap;
94 ResourceMap gFenceNVMap;
95 ResourceMap gFramebufferMap;
96 ResourceMap gMemoryObjectMap;
97 ResourceMap gProgramPipelineMap;
98 ResourceMap gQueryMap;
99 ResourceMap gRenderbufferMap;
100 ResourceMap gSamplerMap;
101 ResourceMap gSemaphoreMap;
102 ResourceMap gShaderProgramMap;
103 ResourceMap gTextureMap;
104 ResourceMap gTransformFeedbackMap;
105 ResourceMap gVertexArrayMap;
106 SyncResourceMap gSyncMap;
107 
SetBinaryDataDecompressCallback(DecompressCallback callback)108 void SetBinaryDataDecompressCallback(DecompressCallback callback)
109 {
110     gDecompressCallback = callback;
111 }
112 
SetBinaryDataDir(const char * dataDir)113 void SetBinaryDataDir(const char *dataDir)
114 {
115     gBinaryDataDir = dataDir;
116 }
117 
InitializeReplay(const char * binaryDataFileName,size_t maxClientArraySize,size_t readBufferSize)118 void InitializeReplay(const char *binaryDataFileName,
119                       size_t maxClientArraySize,
120                       size_t readBufferSize)
121 {
122     LoadBinaryData(binaryDataFileName);
123 
124     for (uint8_t *&clientArray : gClientArrays)
125     {
126         clientArray = new uint8_t[maxClientArraySize];
127     }
128 
129     gReadBuffer = new uint8_t[readBufferSize];
130 }
131 
FinishReplay()132 void FinishReplay()
133 {
134     for (uint8_t *&clientArray : gClientArrays)
135     {
136         delete[] clientArray;
137     }
138     delete[] gReadBuffer;
139 }
140 
UpdateClientArrayPointer(int arrayIndex,const void * data,uint64_t size)141 void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
142 {
143     memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
144 }
145 BufferHandleMap gMappedBufferData;
146 
UpdateClientBufferData(GLuint bufferID,const void * source,GLsizei size)147 void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
148 {
149     memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
150 }
151 
UpdateBufferID(GLuint id,GLsizei readBufferOffset)152 void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
153 {
154     UpdateResourceMap(&gBufferMap, id, readBufferOffset);
155 }
156 
UpdateFenceNVID(GLuint id,GLsizei readBufferOffset)157 void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
158 {
159     UpdateResourceMap(&gFenceNVMap, id, readBufferOffset);
160 }
161 
UpdateFramebufferID(GLuint id,GLsizei readBufferOffset)162 void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
163 {
164     UpdateResourceMap(&gFramebufferMap, id, readBufferOffset);
165 }
166 
UpdateMemoryObjectID(GLuint id,GLsizei readBufferOffset)167 void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
168 {
169     UpdateResourceMap(&gMemoryObjectMap, id, readBufferOffset);
170 }
171 
UpdateProgramPipelineID(GLuint id,GLsizei readBufferOffset)172 void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
173 {
174     UpdateResourceMap(&gProgramPipelineMap, id, readBufferOffset);
175 }
176 
UpdateQueryID(GLuint id,GLsizei readBufferOffset)177 void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
178 {
179     UpdateResourceMap(&gQueryMap, id, readBufferOffset);
180 }
181 
UpdateRenderbufferID(GLuint id,GLsizei readBufferOffset)182 void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
183 {
184     UpdateResourceMap(&gRenderbufferMap, id, readBufferOffset);
185 }
186 
UpdateSamplerID(GLuint id,GLsizei readBufferOffset)187 void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
188 {
189     UpdateResourceMap(&gSamplerMap, id, readBufferOffset);
190 }
191 
UpdateSemaphoreID(GLuint id,GLsizei readBufferOffset)192 void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
193 {
194     UpdateResourceMap(&gSemaphoreMap, id, readBufferOffset);
195 }
196 
UpdateShaderProgramID(GLuint id,GLsizei readBufferOffset)197 void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
198 {
199     UpdateResourceMap(&gShaderProgramMap, id, readBufferOffset);
200 }
201 
UpdateTextureID(GLuint id,GLsizei readBufferOffset)202 void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
203 {
204     UpdateResourceMap(&gTextureMap, id, readBufferOffset);
205 }
206 
UpdateTransformFeedbackID(GLuint id,GLsizei readBufferOffset)207 void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
208 {
209     UpdateResourceMap(&gTransformFeedbackMap, id, readBufferOffset);
210 }
211 
UpdateVertexArrayID(GLuint id,GLsizei readBufferOffset)212 void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
213 {
214     UpdateResourceMap(&gVertexArrayMap, id, readBufferOffset);
215 }
216