xref: /aosp_15_r20/external/angle/src/libANGLE/capture/FrameCapture.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // FrameCapture.h:
7*8975f5c5SAndroid Build Coastguard Worker //   ANGLE Frame capture interface.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_FRAME_CAPTURE_H_
11*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_FRAME_CAPTURE_H_
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/SimpleMutex.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/frame_capture_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ShareGroup.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/entry_points_utils.h"
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker namespace gl
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker enum class BigGLEnum;
26*8975f5c5SAndroid Build Coastguard Worker enum class GLESEnum;
27*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker namespace angle
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker // Helper to use unique IDs for each local data variable.
32*8975f5c5SAndroid Build Coastguard Worker class DataCounters final : angle::NonCopyable
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker   public:
35*8975f5c5SAndroid Build Coastguard Worker     DataCounters();
36*8975f5c5SAndroid Build Coastguard Worker     ~DataCounters();
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker     int getAndIncrement(EntryPoint entryPoint, const std::string &paramName);
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker   private:
41*8975f5c5SAndroid Build Coastguard Worker     // <CallName, ParamName>
42*8975f5c5SAndroid Build Coastguard Worker     using Counter = std::pair<EntryPoint, std::string>;
43*8975f5c5SAndroid Build Coastguard Worker     std::map<Counter, int> mData;
44*8975f5c5SAndroid Build Coastguard Worker };
45*8975f5c5SAndroid Build Coastguard Worker 
46*8975f5c5SAndroid Build Coastguard Worker constexpr int kStringsNotFound = -1;
47*8975f5c5SAndroid Build Coastguard Worker class StringCounters final : angle::NonCopyable
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker   public:
50*8975f5c5SAndroid Build Coastguard Worker     StringCounters();
51*8975f5c5SAndroid Build Coastguard Worker     ~StringCounters();
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     int getStringCounter(const std::vector<std::string> &str);
54*8975f5c5SAndroid Build Coastguard Worker     void setStringCounter(const std::vector<std::string> &str, int &counter);
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker   private:
57*8975f5c5SAndroid Build Coastguard Worker     std::map<std::vector<std::string>, int> mStringCounterMap;
58*8975f5c5SAndroid Build Coastguard Worker };
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker class DataTracker final : angle::NonCopyable
61*8975f5c5SAndroid Build Coastguard Worker {
62*8975f5c5SAndroid Build Coastguard Worker   public:
63*8975f5c5SAndroid Build Coastguard Worker     DataTracker();
64*8975f5c5SAndroid Build Coastguard Worker     ~DataTracker();
65*8975f5c5SAndroid Build Coastguard Worker 
getCounters()66*8975f5c5SAndroid Build Coastguard Worker     DataCounters &getCounters() { return mCounters; }
getStringCounters()67*8975f5c5SAndroid Build Coastguard Worker     StringCounters &getStringCounters() { return mStringCounters; }
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker   private:
70*8975f5c5SAndroid Build Coastguard Worker     DataCounters mCounters;
71*8975f5c5SAndroid Build Coastguard Worker     StringCounters mStringCounters;
72*8975f5c5SAndroid Build Coastguard Worker };
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker class ReplayWriter final : angle::NonCopyable
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker   public:
77*8975f5c5SAndroid Build Coastguard Worker     ReplayWriter();
78*8975f5c5SAndroid Build Coastguard Worker     ~ReplayWriter();
79*8975f5c5SAndroid Build Coastguard Worker 
80*8975f5c5SAndroid Build Coastguard Worker     void setSourceFileExtension(const char *ext);
81*8975f5c5SAndroid Build Coastguard Worker     void setSourceFileSizeThreshold(size_t sourceFileSizeThreshold);
82*8975f5c5SAndroid Build Coastguard Worker     void setFilenamePattern(const std::string &pattern);
83*8975f5c5SAndroid Build Coastguard Worker     void setCaptureLabel(const std::string &label);
84*8975f5c5SAndroid Build Coastguard Worker     void setSourcePrologue(const std::string &prologue);
85*8975f5c5SAndroid Build Coastguard Worker     void setHeaderPrologue(const std::string &prologue);
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker     void addPublicFunction(const std::string &functionProto,
88*8975f5c5SAndroid Build Coastguard Worker                            const std::stringstream &headerStream,
89*8975f5c5SAndroid Build Coastguard Worker                            const std::stringstream &bodyStream);
90*8975f5c5SAndroid Build Coastguard Worker     void addPrivateFunction(const std::string &functionProto,
91*8975f5c5SAndroid Build Coastguard Worker                             const std::stringstream &headerStream,
92*8975f5c5SAndroid Build Coastguard Worker                             const std::stringstream &bodyStream);
93*8975f5c5SAndroid Build Coastguard Worker     std::string getInlineVariableName(EntryPoint entryPoint, const std::string &paramName);
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     std::string getInlineStringSetVariableName(EntryPoint entryPoint,
96*8975f5c5SAndroid Build Coastguard Worker                                                const std::string &paramName,
97*8975f5c5SAndroid Build Coastguard Worker                                                const std::vector<std::string> &strings,
98*8975f5c5SAndroid Build Coastguard Worker                                                bool *isNewEntryOut);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     void saveFrame();
101*8975f5c5SAndroid Build Coastguard Worker     void saveFrameIfFull();
102*8975f5c5SAndroid Build Coastguard Worker     void saveIndexFilesAndHeader();
103*8975f5c5SAndroid Build Coastguard Worker     void saveSetupFile();
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> getAndResetWrittenFiles();
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker   private:
108*8975f5c5SAndroid Build Coastguard Worker     static std::string GetVarName(EntryPoint entryPoint, const std::string &paramName, int counter);
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     void saveHeader();
111*8975f5c5SAndroid Build Coastguard Worker     void writeReplaySource(const std::string &filename);
112*8975f5c5SAndroid Build Coastguard Worker     void addWrittenFile(const std::string &filename);
113*8975f5c5SAndroid Build Coastguard Worker     size_t getStoredReplaySourceSize() const;
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     std::string mSourceFileExtension;
116*8975f5c5SAndroid Build Coastguard Worker     size_t mSourceFileSizeThreshold;
117*8975f5c5SAndroid Build Coastguard Worker     size_t mFrameIndex;
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     DataTracker mDataTracker;
120*8975f5c5SAndroid Build Coastguard Worker     std::string mFilenamePattern;
121*8975f5c5SAndroid Build Coastguard Worker     std::string mCaptureLabel;
122*8975f5c5SAndroid Build Coastguard Worker     std::string mSourcePrologue;
123*8975f5c5SAndroid Build Coastguard Worker     std::string mHeaderPrologue;
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mReplayHeaders;
126*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mGlobalVariableDeclarations;
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mPublicFunctionPrototypes;
129*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mPublicFunctions;
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mPrivateFunctionPrototypes;
132*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mPrivateFunctions;
133*8975f5c5SAndroid Build Coastguard Worker 
134*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> mWrittenFiles;
135*8975f5c5SAndroid Build Coastguard Worker };
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker using BufferCalls = std::map<GLuint, std::vector<CallCapture>>;
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker // true means mapped, false means unmapped
140*8975f5c5SAndroid Build Coastguard Worker using BufferMapStatusMap = std::map<GLuint, bool>;
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker using FenceSyncSet   = std::set<gl::SyncID>;
143*8975f5c5SAndroid Build Coastguard Worker using FenceSyncCalls = std::map<gl::SyncID, std::vector<CallCapture>>;
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker // For default uniforms, we need to track which ones are dirty, and the series of calls to reset.
146*8975f5c5SAndroid Build Coastguard Worker // Each program has unique default uniforms, and each uniform has one or more locations in the
147*8975f5c5SAndroid Build Coastguard Worker // default buffer. For reset efficiency, we track only the uniforms dirty by location, per program.
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker // A set of all default uniforms (per program) that were modified during the run
150*8975f5c5SAndroid Build Coastguard Worker using DefaultUniformLocationsSet = std::set<gl::UniformLocation>;
151*8975f5c5SAndroid Build Coastguard Worker using DefaultUniformLocationsPerProgramMap =
152*8975f5c5SAndroid Build Coastguard Worker     std::map<gl::ShaderProgramID, DefaultUniformLocationsSet>;
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker // A map of programs which maps to locations and their reset calls
155*8975f5c5SAndroid Build Coastguard Worker using DefaultUniformCallsPerLocationMap = std::map<gl::UniformLocation, std::vector<CallCapture>>;
156*8975f5c5SAndroid Build Coastguard Worker using DefaultUniformCallsPerProgramMap =
157*8975f5c5SAndroid Build Coastguard Worker     std::map<gl::ShaderProgramID, DefaultUniformCallsPerLocationMap>;
158*8975f5c5SAndroid Build Coastguard Worker 
159*8975f5c5SAndroid Build Coastguard Worker using DefaultUniformBaseLocationMap =
160*8975f5c5SAndroid Build Coastguard Worker     std::map<std::pair<gl::ShaderProgramID, gl::UniformLocation>, gl::UniformLocation>;
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker using ResourceSet   = std::set<GLuint>;
163*8975f5c5SAndroid Build Coastguard Worker using ResourceCalls = std::map<GLuint, std::vector<CallCapture>>;
164*8975f5c5SAndroid Build Coastguard Worker 
165*8975f5c5SAndroid Build Coastguard Worker class TrackedResource final : angle::NonCopyable
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker   public:
168*8975f5c5SAndroid Build Coastguard Worker     TrackedResource();
169*8975f5c5SAndroid Build Coastguard Worker     ~TrackedResource();
170*8975f5c5SAndroid Build Coastguard Worker 
getStartingResources()171*8975f5c5SAndroid Build Coastguard Worker     const ResourceSet &getStartingResources() const { return mStartingResources; }
getStartingResources()172*8975f5c5SAndroid Build Coastguard Worker     ResourceSet &getStartingResources() { return mStartingResources; }
getNewResources()173*8975f5c5SAndroid Build Coastguard Worker     const ResourceSet &getNewResources() const { return mNewResources; }
getNewResources()174*8975f5c5SAndroid Build Coastguard Worker     ResourceSet &getNewResources() { return mNewResources; }
getResourcesToDelete()175*8975f5c5SAndroid Build Coastguard Worker     const ResourceSet &getResourcesToDelete() const { return mResourcesToDelete; }
getResourcesToDelete()176*8975f5c5SAndroid Build Coastguard Worker     ResourceSet &getResourcesToDelete() { return mResourcesToDelete; }
getResourcesToRegen()177*8975f5c5SAndroid Build Coastguard Worker     const ResourceSet &getResourcesToRegen() const { return mResourcesToRegen; }
getResourcesToRegen()178*8975f5c5SAndroid Build Coastguard Worker     ResourceSet &getResourcesToRegen() { return mResourcesToRegen; }
getResourcesToRestore()179*8975f5c5SAndroid Build Coastguard Worker     const ResourceSet &getResourcesToRestore() const { return mResourcesToRestore; }
getResourcesToRestore()180*8975f5c5SAndroid Build Coastguard Worker     ResourceSet &getResourcesToRestore() { return mResourcesToRestore; }
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker     void setGennedResource(GLuint id);
183*8975f5c5SAndroid Build Coastguard Worker     void setDeletedResource(GLuint id);
184*8975f5c5SAndroid Build Coastguard Worker     void setModifiedResource(GLuint id);
185*8975f5c5SAndroid Build Coastguard Worker     bool resourceIsGenerated(GLuint id);
186*8975f5c5SAndroid Build Coastguard Worker 
getResourceRegenCalls()187*8975f5c5SAndroid Build Coastguard Worker     ResourceCalls &getResourceRegenCalls() { return mResourceRegenCalls; }
getResourceRestoreCalls()188*8975f5c5SAndroid Build Coastguard Worker     ResourceCalls &getResourceRestoreCalls() { return mResourceRestoreCalls; }
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker   private:
191*8975f5c5SAndroid Build Coastguard Worker     // Resource regen calls will gen a resource
192*8975f5c5SAndroid Build Coastguard Worker     ResourceCalls mResourceRegenCalls;
193*8975f5c5SAndroid Build Coastguard Worker     // Resource restore calls will restore the contents of a resource
194*8975f5c5SAndroid Build Coastguard Worker     ResourceCalls mResourceRestoreCalls;
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker     // Resources created during startup
197*8975f5c5SAndroid Build Coastguard Worker     ResourceSet mStartingResources;
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker     // Resources created during the run that need to be deleted
200*8975f5c5SAndroid Build Coastguard Worker     ResourceSet mNewResources;
201*8975f5c5SAndroid Build Coastguard Worker     // Resources recreated during the run that need to be deleted
202*8975f5c5SAndroid Build Coastguard Worker     ResourceSet mResourcesToDelete;
203*8975f5c5SAndroid Build Coastguard Worker     // Resources deleted during the run that need to be recreated
204*8975f5c5SAndroid Build Coastguard Worker     ResourceSet mResourcesToRegen;
205*8975f5c5SAndroid Build Coastguard Worker     // Resources modified during the run that need to be restored
206*8975f5c5SAndroid Build Coastguard Worker     ResourceSet mResourcesToRestore;
207*8975f5c5SAndroid Build Coastguard Worker };
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker using TrackedResourceArray =
210*8975f5c5SAndroid Build Coastguard Worker     std::array<TrackedResource, static_cast<uint32_t>(ResourceIDType::EnumCount)>;
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker enum class ShaderProgramType
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker     ShaderType,
215*8975f5c5SAndroid Build Coastguard Worker     ProgramType
216*8975f5c5SAndroid Build Coastguard Worker };
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker // Helper to track resource changes during the capture
219*8975f5c5SAndroid Build Coastguard Worker class ResourceTracker final : angle::NonCopyable
220*8975f5c5SAndroid Build Coastguard Worker {
221*8975f5c5SAndroid Build Coastguard Worker   public:
222*8975f5c5SAndroid Build Coastguard Worker     ResourceTracker();
223*8975f5c5SAndroid Build Coastguard Worker     ~ResourceTracker();
224*8975f5c5SAndroid Build Coastguard Worker 
getBufferMapCalls()225*8975f5c5SAndroid Build Coastguard Worker     BufferCalls &getBufferMapCalls() { return mBufferMapCalls; }
getBufferUnmapCalls()226*8975f5c5SAndroid Build Coastguard Worker     BufferCalls &getBufferUnmapCalls() { return mBufferUnmapCalls; }
227*8975f5c5SAndroid Build Coastguard Worker 
getBufferBindingCalls()228*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> &getBufferBindingCalls() { return mBufferBindingCalls; }
229*8975f5c5SAndroid Build Coastguard Worker 
230*8975f5c5SAndroid Build Coastguard Worker     void setBufferMapped(gl::ContextID contextID, GLuint id);
231*8975f5c5SAndroid Build Coastguard Worker     void setBufferUnmapped(gl::ContextID contextID, GLuint id);
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     bool getStartingBuffersMappedCurrent(GLuint id) const;
234*8975f5c5SAndroid Build Coastguard Worker     bool getStartingBuffersMappedInitial(GLuint id) const;
235*8975f5c5SAndroid Build Coastguard Worker 
setStartingBufferMapped(GLuint id,bool mapped)236*8975f5c5SAndroid Build Coastguard Worker     void setStartingBufferMapped(GLuint id, bool mapped)
237*8975f5c5SAndroid Build Coastguard Worker     {
238*8975f5c5SAndroid Build Coastguard Worker         // Track the current state (which will change throughout the trace)
239*8975f5c5SAndroid Build Coastguard Worker         mStartingBuffersMappedCurrent[id] = mapped;
240*8975f5c5SAndroid Build Coastguard Worker 
241*8975f5c5SAndroid Build Coastguard Worker         // And the initial state, to compare during frame loop reset
242*8975f5c5SAndroid Build Coastguard Worker         mStartingBuffersMappedInitial[id] = mapped;
243*8975f5c5SAndroid Build Coastguard Worker     }
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker     void onShaderProgramAccess(gl::ShaderProgramID shaderProgramID);
getMaxShaderPrograms()246*8975f5c5SAndroid Build Coastguard Worker     uint32_t getMaxShaderPrograms() const { return mMaxShaderPrograms; }
247*8975f5c5SAndroid Build Coastguard Worker 
getStartingFenceSyncs()248*8975f5c5SAndroid Build Coastguard Worker     FenceSyncSet &getStartingFenceSyncs() { return mStartingFenceSyncs; }
getFenceSyncRegenCalls()249*8975f5c5SAndroid Build Coastguard Worker     FenceSyncCalls &getFenceSyncRegenCalls() { return mFenceSyncRegenCalls; }
getFenceSyncsToRegen()250*8975f5c5SAndroid Build Coastguard Worker     FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; }
251*8975f5c5SAndroid Build Coastguard Worker     void setDeletedFenceSync(gl::SyncID sync);
252*8975f5c5SAndroid Build Coastguard Worker 
getDefaultUniformsToReset()253*8975f5c5SAndroid Build Coastguard Worker     DefaultUniformLocationsPerProgramMap &getDefaultUniformsToReset()
254*8975f5c5SAndroid Build Coastguard Worker     {
255*8975f5c5SAndroid Build Coastguard Worker         return mDefaultUniformsToReset;
256*8975f5c5SAndroid Build Coastguard Worker     }
getDefaultUniformResetCalls(gl::ShaderProgramID id)257*8975f5c5SAndroid Build Coastguard Worker     DefaultUniformCallsPerLocationMap &getDefaultUniformResetCalls(gl::ShaderProgramID id)
258*8975f5c5SAndroid Build Coastguard Worker     {
259*8975f5c5SAndroid Build Coastguard Worker         return mDefaultUniformResetCalls[id];
260*8975f5c5SAndroid Build Coastguard Worker     }
261*8975f5c5SAndroid Build Coastguard Worker     void setModifiedDefaultUniform(gl::ShaderProgramID programID, gl::UniformLocation location);
262*8975f5c5SAndroid Build Coastguard Worker     void setDefaultUniformBaseLocation(gl::ShaderProgramID programID,
263*8975f5c5SAndroid Build Coastguard Worker                                        gl::UniformLocation location,
264*8975f5c5SAndroid Build Coastguard Worker                                        gl::UniformLocation baseLocation);
getDefaultUniformBaseLocation(gl::ShaderProgramID programID,gl::UniformLocation location)265*8975f5c5SAndroid Build Coastguard Worker     gl::UniformLocation getDefaultUniformBaseLocation(gl::ShaderProgramID programID,
266*8975f5c5SAndroid Build Coastguard Worker                                                       gl::UniformLocation location)
267*8975f5c5SAndroid Build Coastguard Worker     {
268*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mDefaultUniformBaseLocations.find({programID, location}) !=
269*8975f5c5SAndroid Build Coastguard Worker                mDefaultUniformBaseLocations.end());
270*8975f5c5SAndroid Build Coastguard Worker         return mDefaultUniformBaseLocations[{programID, location}];
271*8975f5c5SAndroid Build Coastguard Worker     }
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     TrackedResource &getTrackedResource(gl::ContextID contextID, ResourceIDType type);
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     void getContextIDs(std::set<gl::ContextID> &idsOut);
276*8975f5c5SAndroid Build Coastguard Worker 
getImageToAttribTable()277*8975f5c5SAndroid Build Coastguard Worker     std::map<EGLImage, egl::AttributeMap> &getImageToAttribTable() { return mMatchImageToAttribs; }
278*8975f5c5SAndroid Build Coastguard Worker 
getTextureIDToImageTable()279*8975f5c5SAndroid Build Coastguard Worker     std::map<GLuint, egl::ImageID> &getTextureIDToImageTable() { return mMatchTextureIDToImage; }
280*8975f5c5SAndroid Build Coastguard Worker 
setShaderProgramType(gl::ShaderProgramID id,angle::ShaderProgramType type)281*8975f5c5SAndroid Build Coastguard Worker     void setShaderProgramType(gl::ShaderProgramID id, angle::ShaderProgramType type)
282*8975f5c5SAndroid Build Coastguard Worker     {
283*8975f5c5SAndroid Build Coastguard Worker         mShaderProgramType[id] = type;
284*8975f5c5SAndroid Build Coastguard Worker     }
getShaderProgramType(gl::ShaderProgramID id)285*8975f5c5SAndroid Build Coastguard Worker     ShaderProgramType getShaderProgramType(gl::ShaderProgramID id)
286*8975f5c5SAndroid Build Coastguard Worker     {
287*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mShaderProgramType.find(id) != mShaderProgramType.end());
288*8975f5c5SAndroid Build Coastguard Worker         return mShaderProgramType[id];
289*8975f5c5SAndroid Build Coastguard Worker     }
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker   private:
292*8975f5c5SAndroid Build Coastguard Worker     // Buffer map calls will map a buffer with correct offset, length, and access flags
293*8975f5c5SAndroid Build Coastguard Worker     BufferCalls mBufferMapCalls;
294*8975f5c5SAndroid Build Coastguard Worker     // Buffer unmap calls will bind and unmap a given buffer
295*8975f5c5SAndroid Build Coastguard Worker     BufferCalls mBufferUnmapCalls;
296*8975f5c5SAndroid Build Coastguard Worker 
297*8975f5c5SAndroid Build Coastguard Worker     // Buffer binding calls to restore bindings recorded during MEC
298*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> mBufferBindingCalls;
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     // Whether a given buffer was mapped at the start of the trace
301*8975f5c5SAndroid Build Coastguard Worker     BufferMapStatusMap mStartingBuffersMappedInitial;
302*8975f5c5SAndroid Build Coastguard Worker     // The status of buffer mapping throughout the trace, modified with each Map/Unmap call
303*8975f5c5SAndroid Build Coastguard Worker     BufferMapStatusMap mStartingBuffersMappedCurrent;
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker     // Maximum accessed shader program ID.
306*8975f5c5SAndroid Build Coastguard Worker     uint32_t mMaxShaderPrograms = 0;
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     // Fence sync objects created during MEC setup
309*8975f5c5SAndroid Build Coastguard Worker     FenceSyncSet mStartingFenceSyncs;
310*8975f5c5SAndroid Build Coastguard Worker     // Fence sync regen calls will create a fence sync objects
311*8975f5c5SAndroid Build Coastguard Worker     FenceSyncCalls mFenceSyncRegenCalls;
312*8975f5c5SAndroid Build Coastguard Worker     // Fence syncs to regen are a list of starting fence sync objects that were deleted and need to
313*8975f5c5SAndroid Build Coastguard Worker     // be regen'ed.
314*8975f5c5SAndroid Build Coastguard Worker     FenceSyncSet mFenceSyncsToRegen;
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker     // Default uniforms that were modified during the run
317*8975f5c5SAndroid Build Coastguard Worker     DefaultUniformLocationsPerProgramMap mDefaultUniformsToReset;
318*8975f5c5SAndroid Build Coastguard Worker     // Calls per default uniform to return to original state
319*8975f5c5SAndroid Build Coastguard Worker     DefaultUniformCallsPerProgramMap mDefaultUniformResetCalls;
320*8975f5c5SAndroid Build Coastguard Worker 
321*8975f5c5SAndroid Build Coastguard Worker     // Base location of arrayed uniforms
322*8975f5c5SAndroid Build Coastguard Worker     DefaultUniformBaseLocationMap mDefaultUniformBaseLocations;
323*8975f5c5SAndroid Build Coastguard Worker 
324*8975f5c5SAndroid Build Coastguard Worker     // Tracked resources per context
325*8975f5c5SAndroid Build Coastguard Worker     TrackedResourceArray mTrackedResourcesShared;
326*8975f5c5SAndroid Build Coastguard Worker     std::map<gl::ContextID, TrackedResourceArray> mTrackedResourcesPerContext;
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     std::map<EGLImage, egl::AttributeMap> mMatchImageToAttribs;
329*8975f5c5SAndroid Build Coastguard Worker     std::map<GLuint, egl::ImageID> mMatchTextureIDToImage;
330*8975f5c5SAndroid Build Coastguard Worker 
331*8975f5c5SAndroid Build Coastguard Worker     std::map<gl::ShaderProgramID, ShaderProgramType> mShaderProgramType;
332*8975f5c5SAndroid Build Coastguard Worker };
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker // Used by the CPP replay to filter out unnecessary code.
335*8975f5c5SAndroid Build Coastguard Worker using HasResourceTypeMap = angle::PackedEnumBitSet<ResourceIDType>;
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker // Map of ResourceType to IDs and range of setup calls
338*8975f5c5SAndroid Build Coastguard Worker using ResourceIDToSetupCallsMap =
339*8975f5c5SAndroid Build Coastguard Worker     PackedEnumMap<ResourceIDType, std::map<GLuint, gl::Range<size_t>>>;
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker // Map of buffer ID to offset and size used when mapped
342*8975f5c5SAndroid Build Coastguard Worker using BufferDataMap = std::map<gl::BufferID, std::pair<GLintptr, GLsizeiptr>>;
343*8975f5c5SAndroid Build Coastguard Worker 
344*8975f5c5SAndroid Build Coastguard Worker // A dictionary of sources indexed by shader type.
345*8975f5c5SAndroid Build Coastguard Worker using ProgramSources = gl::ShaderMap<std::string>;
346*8975f5c5SAndroid Build Coastguard Worker 
347*8975f5c5SAndroid Build Coastguard Worker // Maps from IDs to sources.
348*8975f5c5SAndroid Build Coastguard Worker using ShaderSourceMap  = std::map<gl::ShaderProgramID, std::string>;
349*8975f5c5SAndroid Build Coastguard Worker using ProgramSourceMap = std::map<gl::ShaderProgramID, ProgramSources>;
350*8975f5c5SAndroid Build Coastguard Worker 
351*8975f5c5SAndroid Build Coastguard Worker // Map from textureID to level and data
352*8975f5c5SAndroid Build Coastguard Worker using TextureLevels       = std::map<GLint, std::vector<uint8_t>>;
353*8975f5c5SAndroid Build Coastguard Worker using TextureLevelDataMap = std::map<gl::TextureID, TextureLevels>;
354*8975f5c5SAndroid Build Coastguard Worker 
355*8975f5c5SAndroid Build Coastguard Worker struct SurfaceParams
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker     gl::Extents extents;
358*8975f5c5SAndroid Build Coastguard Worker     egl::ColorSpace colorSpace;
359*8975f5c5SAndroid Build Coastguard Worker };
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker // Map from ContextID to SurfaceParams
362*8975f5c5SAndroid Build Coastguard Worker using SurfaceParamsMap = std::map<gl::ContextID, SurfaceParams>;
363*8975f5c5SAndroid Build Coastguard Worker 
364*8975f5c5SAndroid Build Coastguard Worker using CallVector = std::vector<std::vector<CallCapture> *>;
365*8975f5c5SAndroid Build Coastguard Worker 
366*8975f5c5SAndroid Build Coastguard Worker // A map from API entry point to calls
367*8975f5c5SAndroid Build Coastguard Worker using CallResetMap = std::map<angle::EntryPoint, std::vector<CallCapture>>;
368*8975f5c5SAndroid Build Coastguard Worker 
369*8975f5c5SAndroid Build Coastguard Worker using TextureBinding  = std::pair<size_t, gl::TextureType>;
370*8975f5c5SAndroid Build Coastguard Worker using TextureResetMap = std::map<TextureBinding, gl::TextureID>;
371*8975f5c5SAndroid Build Coastguard Worker 
372*8975f5c5SAndroid Build Coastguard Worker using BufferBindingPair = std::pair<gl::BufferBinding, gl::BufferID>;
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker // StateResetHelper provides a simple way to track whether an entry point has been called during the
375*8975f5c5SAndroid Build Coastguard Worker // trace, along with the reset calls to get it back to starting state.  This is useful for things
376*8975f5c5SAndroid Build Coastguard Worker // that are one dimensional, like context bindings or context state.
377*8975f5c5SAndroid Build Coastguard Worker class StateResetHelper final : angle::NonCopyable
378*8975f5c5SAndroid Build Coastguard Worker {
379*8975f5c5SAndroid Build Coastguard Worker   public:
380*8975f5c5SAndroid Build Coastguard Worker     StateResetHelper();
381*8975f5c5SAndroid Build Coastguard Worker     ~StateResetHelper();
382*8975f5c5SAndroid Build Coastguard Worker 
getDirtyEntryPoints()383*8975f5c5SAndroid Build Coastguard Worker     const std::set<angle::EntryPoint> &getDirtyEntryPoints() const { return mDirtyEntryPoints; }
setEntryPointDirty(EntryPoint entryPoint)384*8975f5c5SAndroid Build Coastguard Worker     void setEntryPointDirty(EntryPoint entryPoint) { mDirtyEntryPoints.insert(entryPoint); }
385*8975f5c5SAndroid Build Coastguard Worker 
getResetCalls()386*8975f5c5SAndroid Build Coastguard Worker     CallResetMap &getResetCalls() { return mResetCalls; }
getResetCalls()387*8975f5c5SAndroid Build Coastguard Worker     const CallResetMap &getResetCalls() const { return mResetCalls; }
388*8975f5c5SAndroid Build Coastguard Worker 
389*8975f5c5SAndroid Build Coastguard Worker     void setDefaultResetCalls(const gl::Context *context, angle::EntryPoint);
390*8975f5c5SAndroid Build Coastguard Worker 
getDirtyTextureBindings()391*8975f5c5SAndroid Build Coastguard Worker     const std::set<TextureBinding> &getDirtyTextureBindings() const
392*8975f5c5SAndroid Build Coastguard Worker     {
393*8975f5c5SAndroid Build Coastguard Worker         return mDirtyTextureBindings;
394*8975f5c5SAndroid Build Coastguard Worker     }
setTextureBindingDirty(size_t unit,gl::TextureType target)395*8975f5c5SAndroid Build Coastguard Worker     void setTextureBindingDirty(size_t unit, gl::TextureType target)
396*8975f5c5SAndroid Build Coastguard Worker     {
397*8975f5c5SAndroid Build Coastguard Worker         mDirtyTextureBindings.emplace(unit, target);
398*8975f5c5SAndroid Build Coastguard Worker     }
399*8975f5c5SAndroid Build Coastguard Worker 
getResetTextureBindings()400*8975f5c5SAndroid Build Coastguard Worker     TextureResetMap &getResetTextureBindings() { return mResetTextureBindings; }
401*8975f5c5SAndroid Build Coastguard Worker 
setResetActiveTexture(size_t textureID)402*8975f5c5SAndroid Build Coastguard Worker     void setResetActiveTexture(size_t textureID) { mResetActiveTexture = textureID; }
getResetActiveTexture()403*8975f5c5SAndroid Build Coastguard Worker     size_t getResetActiveTexture() { return mResetActiveTexture; }
404*8975f5c5SAndroid Build Coastguard Worker 
getDirtyBufferBindings()405*8975f5c5SAndroid Build Coastguard Worker     const std::set<gl::BufferBinding> &getDirtyBufferBindings() const
406*8975f5c5SAndroid Build Coastguard Worker     {
407*8975f5c5SAndroid Build Coastguard Worker         return mDirtyBufferBindings;
408*8975f5c5SAndroid Build Coastguard Worker     }
setBufferBindingDirty(gl::BufferBinding binding)409*8975f5c5SAndroid Build Coastguard Worker     void setBufferBindingDirty(gl::BufferBinding binding) { mDirtyBufferBindings.insert(binding); }
410*8975f5c5SAndroid Build Coastguard Worker 
getStartingBufferBindings()411*8975f5c5SAndroid Build Coastguard Worker     const std::set<BufferBindingPair> &getStartingBufferBindings() const
412*8975f5c5SAndroid Build Coastguard Worker     {
413*8975f5c5SAndroid Build Coastguard Worker         return mStartingBufferBindings;
414*8975f5c5SAndroid Build Coastguard Worker     }
setStartingBufferBinding(gl::BufferBinding binding,gl::BufferID bufferID)415*8975f5c5SAndroid Build Coastguard Worker     void setStartingBufferBinding(gl::BufferBinding binding, gl::BufferID bufferID)
416*8975f5c5SAndroid Build Coastguard Worker     {
417*8975f5c5SAndroid Build Coastguard Worker         mStartingBufferBindings.insert({binding, bufferID});
418*8975f5c5SAndroid Build Coastguard Worker     }
419*8975f5c5SAndroid Build Coastguard Worker 
420*8975f5c5SAndroid Build Coastguard Worker   private:
421*8975f5c5SAndroid Build Coastguard Worker     // Dirty state per entry point
422*8975f5c5SAndroid Build Coastguard Worker     std::set<angle::EntryPoint> mDirtyEntryPoints;
423*8975f5c5SAndroid Build Coastguard Worker 
424*8975f5c5SAndroid Build Coastguard Worker     // Reset calls per API entry point
425*8975f5c5SAndroid Build Coastguard Worker     CallResetMap mResetCalls;
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker     // Dirty state per texture binding
428*8975f5c5SAndroid Build Coastguard Worker     std::set<TextureBinding> mDirtyTextureBindings;
429*8975f5c5SAndroid Build Coastguard Worker 
430*8975f5c5SAndroid Build Coastguard Worker     // Texture bindings and active texture to restore
431*8975f5c5SAndroid Build Coastguard Worker     TextureResetMap mResetTextureBindings;
432*8975f5c5SAndroid Build Coastguard Worker     size_t mResetActiveTexture = 0;
433*8975f5c5SAndroid Build Coastguard Worker 
434*8975f5c5SAndroid Build Coastguard Worker     // Starting and dirty buffer bindings
435*8975f5c5SAndroid Build Coastguard Worker     std::set<BufferBindingPair> mStartingBufferBindings;
436*8975f5c5SAndroid Build Coastguard Worker     std::set<gl::BufferBinding> mDirtyBufferBindings;
437*8975f5c5SAndroid Build Coastguard Worker };
438*8975f5c5SAndroid Build Coastguard Worker 
439*8975f5c5SAndroid Build Coastguard Worker class FrameCapture final : angle::NonCopyable
440*8975f5c5SAndroid Build Coastguard Worker {
441*8975f5c5SAndroid Build Coastguard Worker   public:
442*8975f5c5SAndroid Build Coastguard Worker     FrameCapture();
443*8975f5c5SAndroid Build Coastguard Worker     ~FrameCapture();
444*8975f5c5SAndroid Build Coastguard Worker 
getSetupCalls()445*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> &getSetupCalls() { return mSetupCalls; }
clearSetupCalls()446*8975f5c5SAndroid Build Coastguard Worker     void clearSetupCalls() { mSetupCalls.clear(); }
447*8975f5c5SAndroid Build Coastguard Worker 
getStateResetHelper()448*8975f5c5SAndroid Build Coastguard Worker     StateResetHelper &getStateResetHelper() { return mStateResetHelper; }
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker     void reset();
451*8975f5c5SAndroid Build Coastguard Worker 
452*8975f5c5SAndroid Build Coastguard Worker   private:
453*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> mSetupCalls;
454*8975f5c5SAndroid Build Coastguard Worker 
455*8975f5c5SAndroid Build Coastguard Worker     StateResetHelper mStateResetHelper;
456*8975f5c5SAndroid Build Coastguard Worker };
457*8975f5c5SAndroid Build Coastguard Worker 
458*8975f5c5SAndroid Build Coastguard Worker // Page range inside a coherent buffer
459*8975f5c5SAndroid Build Coastguard Worker struct PageRange
460*8975f5c5SAndroid Build Coastguard Worker {
461*8975f5c5SAndroid Build Coastguard Worker     PageRange(size_t start, size_t end);
462*8975f5c5SAndroid Build Coastguard Worker     ~PageRange();
463*8975f5c5SAndroid Build Coastguard Worker 
464*8975f5c5SAndroid Build Coastguard Worker     // Relative start page
465*8975f5c5SAndroid Build Coastguard Worker     size_t start;
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker     // First page after the relative end
468*8975f5c5SAndroid Build Coastguard Worker     size_t end;
469*8975f5c5SAndroid Build Coastguard Worker };
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker // Memory address range defined by start and size
472*8975f5c5SAndroid Build Coastguard Worker struct AddressRange
473*8975f5c5SAndroid Build Coastguard Worker {
474*8975f5c5SAndroid Build Coastguard Worker     AddressRange();
475*8975f5c5SAndroid Build Coastguard Worker     AddressRange(uintptr_t start, size_t size);
476*8975f5c5SAndroid Build Coastguard Worker     ~AddressRange();
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     uintptr_t end();
479*8975f5c5SAndroid Build Coastguard Worker 
480*8975f5c5SAndroid Build Coastguard Worker     uintptr_t start;
481*8975f5c5SAndroid Build Coastguard Worker     size_t size;
482*8975f5c5SAndroid Build Coastguard Worker };
483*8975f5c5SAndroid Build Coastguard Worker 
484*8975f5c5SAndroid Build Coastguard Worker // Used to handle protection of buffers that overlap in pages.
485*8975f5c5SAndroid Build Coastguard Worker enum class PageSharingType
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker     NoneShared,
488*8975f5c5SAndroid Build Coastguard Worker     FirstShared,
489*8975f5c5SAndroid Build Coastguard Worker     LastShared,
490*8975f5c5SAndroid Build Coastguard Worker     FirstAndLastShared
491*8975f5c5SAndroid Build Coastguard Worker };
492*8975f5c5SAndroid Build Coastguard Worker 
493*8975f5c5SAndroid Build Coastguard Worker class CoherentBuffer
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker   public:
496*8975f5c5SAndroid Build Coastguard Worker     CoherentBuffer(uintptr_t start, size_t size, size_t pageSize, bool useShadowMemory);
497*8975f5c5SAndroid Build Coastguard Worker     ~CoherentBuffer();
498*8975f5c5SAndroid Build Coastguard Worker 
499*8975f5c5SAndroid Build Coastguard Worker     // Sets the a range in the buffer clean and protects a selected range
500*8975f5c5SAndroid Build Coastguard Worker     void protectPageRange(const PageRange &pageRange);
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker     // Sets all pages to clean and enables protection
503*8975f5c5SAndroid Build Coastguard Worker     void protectAll();
504*8975f5c5SAndroid Build Coastguard Worker 
505*8975f5c5SAndroid Build Coastguard Worker     // Sets a page dirty state and sets it's protection
506*8975f5c5SAndroid Build Coastguard Worker     void setDirty(size_t relativePage, bool dirty);
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     // Shadow memory synchronization
509*8975f5c5SAndroid Build Coastguard Worker     void updateBufferMemory();
510*8975f5c5SAndroid Build Coastguard Worker     void updateShadowMemory();
511*8975f5c5SAndroid Build Coastguard Worker 
512*8975f5c5SAndroid Build Coastguard Worker     // Removes protection
513*8975f5c5SAndroid Build Coastguard Worker     void removeProtection(PageSharingType sharingType);
514*8975f5c5SAndroid Build Coastguard Worker 
515*8975f5c5SAndroid Build Coastguard Worker     bool contains(size_t page, size_t *relativePage);
516*8975f5c5SAndroid Build Coastguard Worker     bool isDirty();
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker     // Returns dirty page ranges
519*8975f5c5SAndroid Build Coastguard Worker     std::vector<PageRange> getDirtyPageRanges();
520*8975f5c5SAndroid Build Coastguard Worker 
521*8975f5c5SAndroid Build Coastguard Worker     // Calculates address range from page range
522*8975f5c5SAndroid Build Coastguard Worker     AddressRange getDirtyAddressRange(const PageRange &dirtyPageRange);
523*8975f5c5SAndroid Build Coastguard Worker     AddressRange getRange();
524*8975f5c5SAndroid Build Coastguard Worker 
markShadowDirty()525*8975f5c5SAndroid Build Coastguard Worker     void markShadowDirty() { mShadowDirty = true; }
isShadowDirty()526*8975f5c5SAndroid Build Coastguard Worker     bool isShadowDirty() { return mShadowDirty; }
527*8975f5c5SAndroid Build Coastguard Worker 
528*8975f5c5SAndroid Build Coastguard Worker   private:
529*8975f5c5SAndroid Build Coastguard Worker     // Actual buffer start and size
530*8975f5c5SAndroid Build Coastguard Worker     AddressRange mRange;
531*8975f5c5SAndroid Build Coastguard Worker 
532*8975f5c5SAndroid Build Coastguard Worker     // Start and size of page aligned protected area
533*8975f5c5SAndroid Build Coastguard Worker     AddressRange mProtectionRange;
534*8975f5c5SAndroid Build Coastguard Worker 
535*8975f5c5SAndroid Build Coastguard Worker     // Start and end of protection in relative pages, calculated from mProtectionRange.
536*8975f5c5SAndroid Build Coastguard Worker     size_t mProtectionStartPage;
537*8975f5c5SAndroid Build Coastguard Worker     size_t mProtectionEndPage;
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker     size_t mPageCount;
540*8975f5c5SAndroid Build Coastguard Worker     size_t mPageSize;
541*8975f5c5SAndroid Build Coastguard Worker 
542*8975f5c5SAndroid Build Coastguard Worker     // Clean pages are protected
543*8975f5c5SAndroid Build Coastguard Worker     std::vector<bool> mDirtyPages;
544*8975f5c5SAndroid Build Coastguard Worker 
545*8975f5c5SAndroid Build Coastguard Worker     // shadow memory releated fields
546*8975f5c5SAndroid Build Coastguard Worker     bool mShadowMemoryEnabled;
547*8975f5c5SAndroid Build Coastguard Worker     uintptr_t mBufferStart;
548*8975f5c5SAndroid Build Coastguard Worker     void *mShadowMemory;
549*8975f5c5SAndroid Build Coastguard Worker     bool mShadowDirty;
550*8975f5c5SAndroid Build Coastguard Worker };
551*8975f5c5SAndroid Build Coastguard Worker 
552*8975f5c5SAndroid Build Coastguard Worker class CoherentBufferTracker final : angle::NonCopyable
553*8975f5c5SAndroid Build Coastguard Worker {
554*8975f5c5SAndroid Build Coastguard Worker   public:
555*8975f5c5SAndroid Build Coastguard Worker     CoherentBufferTracker();
556*8975f5c5SAndroid Build Coastguard Worker     ~CoherentBufferTracker();
557*8975f5c5SAndroid Build Coastguard Worker 
558*8975f5c5SAndroid Build Coastguard Worker     bool isDirty(gl::BufferID id);
559*8975f5c5SAndroid Build Coastguard Worker     uintptr_t addBuffer(gl::BufferID id, uintptr_t start, size_t size);
560*8975f5c5SAndroid Build Coastguard Worker     void removeBuffer(gl::BufferID id);
561*8975f5c5SAndroid Build Coastguard Worker     void disable();
562*8975f5c5SAndroid Build Coastguard Worker     void enable();
563*8975f5c5SAndroid Build Coastguard Worker     void onEndFrame();
564*8975f5c5SAndroid Build Coastguard Worker     bool haveBuffer(gl::BufferID id);
isShadowMemoryEnabled()565*8975f5c5SAndroid Build Coastguard Worker     bool isShadowMemoryEnabled() { return mShadowMemoryEnabled; }
enableShadowMemory()566*8975f5c5SAndroid Build Coastguard Worker     void enableShadowMemory() { mShadowMemoryEnabled = true; }
567*8975f5c5SAndroid Build Coastguard Worker     void maybeUpdateShadowMemory();
568*8975f5c5SAndroid Build Coastguard Worker     void markAllShadowDirty();
569*8975f5c5SAndroid Build Coastguard Worker     // Determine whether memory protection can be used directly on graphics memory
570*8975f5c5SAndroid Build Coastguard Worker     bool canProtectDirectly(gl::Context *context);
571*8975f5c5SAndroid Build Coastguard Worker 
572*8975f5c5SAndroid Build Coastguard Worker   private:
573*8975f5c5SAndroid Build Coastguard Worker     // Detect overlapping pages when removing protection
574*8975f5c5SAndroid Build Coastguard Worker     PageSharingType doesBufferSharePage(gl::BufferID id);
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker     // Returns a map to found buffers and the corresponding pages for a given address.
577*8975f5c5SAndroid Build Coastguard Worker     // For addresses that are in a page shared by 2 buffers, 2 results are returned.
578*8975f5c5SAndroid Build Coastguard Worker     HashMap<std::shared_ptr<CoherentBuffer>, size_t> getBufferPagesForAddress(uintptr_t address);
579*8975f5c5SAndroid Build Coastguard Worker     PageFaultHandlerRangeType handleWrite(uintptr_t address);
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker   public:
582*8975f5c5SAndroid Build Coastguard Worker     angle::SimpleMutex mMutex;
583*8975f5c5SAndroid Build Coastguard Worker     HashMap<GLuint, std::shared_ptr<CoherentBuffer>> mBuffers;
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker   private:
586*8975f5c5SAndroid Build Coastguard Worker     bool mEnabled;
587*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<PageFaultHandler> mPageFaultHandler;
588*8975f5c5SAndroid Build Coastguard Worker     size_t mPageSize;
589*8975f5c5SAndroid Build Coastguard Worker 
590*8975f5c5SAndroid Build Coastguard Worker     bool mShadowMemoryEnabled;
591*8975f5c5SAndroid Build Coastguard Worker };
592*8975f5c5SAndroid Build Coastguard Worker 
593*8975f5c5SAndroid Build Coastguard Worker // Shared class for any items that need to be tracked by FrameCapture across shared contexts
594*8975f5c5SAndroid Build Coastguard Worker class FrameCaptureShared final : angle::NonCopyable
595*8975f5c5SAndroid Build Coastguard Worker {
596*8975f5c5SAndroid Build Coastguard Worker   public:
597*8975f5c5SAndroid Build Coastguard Worker     FrameCaptureShared();
598*8975f5c5SAndroid Build Coastguard Worker     ~FrameCaptureShared();
599*8975f5c5SAndroid Build Coastguard Worker 
600*8975f5c5SAndroid Build Coastguard Worker     void captureCall(gl::Context *context, CallCapture &&call, bool isCallValid);
601*8975f5c5SAndroid Build Coastguard Worker     void checkForCaptureTrigger();
602*8975f5c5SAndroid Build Coastguard Worker     void onEndFrame(gl::Context *context);
603*8975f5c5SAndroid Build Coastguard Worker     void onDestroyContext(const gl::Context *context);
604*8975f5c5SAndroid Build Coastguard Worker     void onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface);
enabled()605*8975f5c5SAndroid Build Coastguard Worker     bool enabled() const { return mEnabled; }
606*8975f5c5SAndroid Build Coastguard Worker 
607*8975f5c5SAndroid Build Coastguard Worker     bool isCapturing() const;
608*8975f5c5SAndroid Build Coastguard Worker     uint32_t getFrameCount() const;
609*8975f5c5SAndroid Build Coastguard Worker 
610*8975f5c5SAndroid Build Coastguard Worker     // Returns a frame index starting from "1" as the first frame.
611*8975f5c5SAndroid Build Coastguard Worker     uint32_t getReplayFrameIndex() const;
612*8975f5c5SAndroid Build Coastguard Worker 
613*8975f5c5SAndroid Build Coastguard Worker     void trackBufferMapping(const gl::Context *context,
614*8975f5c5SAndroid Build Coastguard Worker                             CallCapture *call,
615*8975f5c5SAndroid Build Coastguard Worker                             gl::BufferID id,
616*8975f5c5SAndroid Build Coastguard Worker                             gl::Buffer *buffer,
617*8975f5c5SAndroid Build Coastguard Worker                             GLintptr offset,
618*8975f5c5SAndroid Build Coastguard Worker                             GLsizeiptr length,
619*8975f5c5SAndroid Build Coastguard Worker                             bool writable,
620*8975f5c5SAndroid Build Coastguard Worker                             bool coherent);
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker     void trackTextureUpdate(const gl::Context *context, const CallCapture &call);
623*8975f5c5SAndroid Build Coastguard Worker     void trackImageUpdate(const gl::Context *context, const CallCapture &call);
624*8975f5c5SAndroid Build Coastguard Worker     void trackDefaultUniformUpdate(const gl::Context *context, const CallCapture &call);
625*8975f5c5SAndroid Build Coastguard Worker     void trackVertexArrayUpdate(const gl::Context *context, const CallCapture &call);
626*8975f5c5SAndroid Build Coastguard Worker 
627*8975f5c5SAndroid Build Coastguard Worker     const std::string &getShaderSource(gl::ShaderProgramID id) const;
628*8975f5c5SAndroid Build Coastguard Worker     void setShaderSource(gl::ShaderProgramID id, std::string sources);
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     const ProgramSources &getProgramSources(gl::ShaderProgramID id) const;
631*8975f5c5SAndroid Build Coastguard Worker     void setProgramSources(gl::ShaderProgramID id, ProgramSources sources);
632*8975f5c5SAndroid Build Coastguard Worker 
633*8975f5c5SAndroid Build Coastguard Worker     // Load data from a previously stored texture level
634*8975f5c5SAndroid Build Coastguard Worker     const std::vector<uint8_t> &retrieveCachedTextureLevel(gl::TextureID id,
635*8975f5c5SAndroid Build Coastguard Worker                                                            gl::TextureTarget target,
636*8975f5c5SAndroid Build Coastguard Worker                                                            GLint level);
637*8975f5c5SAndroid Build Coastguard Worker 
638*8975f5c5SAndroid Build Coastguard Worker     // Create new texture level data and copy the source into it
639*8975f5c5SAndroid Build Coastguard Worker     void copyCachedTextureLevel(const gl::Context *context,
640*8975f5c5SAndroid Build Coastguard Worker                                 gl::TextureID srcID,
641*8975f5c5SAndroid Build Coastguard Worker                                 GLint srcLevel,
642*8975f5c5SAndroid Build Coastguard Worker                                 gl::TextureID dstID,
643*8975f5c5SAndroid Build Coastguard Worker                                 GLint dstLevel,
644*8975f5c5SAndroid Build Coastguard Worker                                 const CallCapture &call);
645*8975f5c5SAndroid Build Coastguard Worker 
646*8975f5c5SAndroid Build Coastguard Worker     // Create the location that should be used to cache texture level data
647*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> &getCachedTextureLevelData(gl::Texture *texture,
648*8975f5c5SAndroid Build Coastguard Worker                                                     gl::TextureTarget target,
649*8975f5c5SAndroid Build Coastguard Worker                                                     GLint level,
650*8975f5c5SAndroid Build Coastguard Worker                                                     EntryPoint entryPoint);
651*8975f5c5SAndroid Build Coastguard Worker 
652*8975f5c5SAndroid Build Coastguard Worker     // Capture coherent buffer storages
653*8975f5c5SAndroid Build Coastguard Worker     void captureCoherentBufferSnapshot(const gl::Context *context, gl::BufferID bufferID);
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker     // Remove any cached texture levels on deletion
656*8975f5c5SAndroid Build Coastguard Worker     void deleteCachedTextureLevelData(gl::TextureID id);
657*8975f5c5SAndroid Build Coastguard Worker 
eraseBufferDataMapEntry(const gl::BufferID bufferId)658*8975f5c5SAndroid Build Coastguard Worker     void eraseBufferDataMapEntry(const gl::BufferID bufferId)
659*8975f5c5SAndroid Build Coastguard Worker     {
660*8975f5c5SAndroid Build Coastguard Worker         const auto &bufferDataInfo = mBufferDataMap.find(bufferId);
661*8975f5c5SAndroid Build Coastguard Worker         if (bufferDataInfo != mBufferDataMap.end())
662*8975f5c5SAndroid Build Coastguard Worker         {
663*8975f5c5SAndroid Build Coastguard Worker             mBufferDataMap.erase(bufferDataInfo);
664*8975f5c5SAndroid Build Coastguard Worker         }
665*8975f5c5SAndroid Build Coastguard Worker     }
666*8975f5c5SAndroid Build Coastguard Worker 
hasBufferData(gl::BufferID bufferID)667*8975f5c5SAndroid Build Coastguard Worker     bool hasBufferData(gl::BufferID bufferID)
668*8975f5c5SAndroid Build Coastguard Worker     {
669*8975f5c5SAndroid Build Coastguard Worker         const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
670*8975f5c5SAndroid Build Coastguard Worker         if (bufferDataInfo != mBufferDataMap.end())
671*8975f5c5SAndroid Build Coastguard Worker         {
672*8975f5c5SAndroid Build Coastguard Worker             return true;
673*8975f5c5SAndroid Build Coastguard Worker         }
674*8975f5c5SAndroid Build Coastguard Worker         return false;
675*8975f5c5SAndroid Build Coastguard Worker     }
676*8975f5c5SAndroid Build Coastguard Worker 
getBufferDataOffsetAndLength(gl::BufferID bufferID)677*8975f5c5SAndroid Build Coastguard Worker     std::pair<GLintptr, GLsizeiptr> getBufferDataOffsetAndLength(gl::BufferID bufferID)
678*8975f5c5SAndroid Build Coastguard Worker     {
679*8975f5c5SAndroid Build Coastguard Worker         const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
680*8975f5c5SAndroid Build Coastguard Worker         ASSERT(bufferDataInfo != mBufferDataMap.end());
681*8975f5c5SAndroid Build Coastguard Worker         return bufferDataInfo->second;
682*8975f5c5SAndroid Build Coastguard Worker     }
683*8975f5c5SAndroid Build Coastguard Worker 
setCaptureActive()684*8975f5c5SAndroid Build Coastguard Worker     void setCaptureActive() { mCaptureActive = true; }
setCaptureInactive()685*8975f5c5SAndroid Build Coastguard Worker     void setCaptureInactive() { mCaptureActive = false; }
isCaptureActive()686*8975f5c5SAndroid Build Coastguard Worker     bool isCaptureActive() { return mCaptureActive; }
usesMidExecutionCapture()687*8975f5c5SAndroid Build Coastguard Worker     bool usesMidExecutionCapture() { return mCaptureStartFrame > 1; }
688*8975f5c5SAndroid Build Coastguard Worker 
getWindowSurfaceContextID()689*8975f5c5SAndroid Build Coastguard Worker     gl::ContextID getWindowSurfaceContextID() const { return mWindowSurfaceContextID; }
690*8975f5c5SAndroid Build Coastguard Worker 
691*8975f5c5SAndroid Build Coastguard Worker     void markResourceSetupCallsInactive(std::vector<CallCapture> *setupCalls,
692*8975f5c5SAndroid Build Coastguard Worker                                         ResourceIDType type,
693*8975f5c5SAndroid Build Coastguard Worker                                         GLuint id,
694*8975f5c5SAndroid Build Coastguard Worker                                         gl::Range<size_t> range);
695*8975f5c5SAndroid Build Coastguard Worker 
updateReadBufferSize(size_t readBufferSize)696*8975f5c5SAndroid Build Coastguard Worker     void updateReadBufferSize(size_t readBufferSize)
697*8975f5c5SAndroid Build Coastguard Worker     {
698*8975f5c5SAndroid Build Coastguard Worker         mReadBufferSize = std::max(mReadBufferSize, readBufferSize);
699*8975f5c5SAndroid Build Coastguard Worker     }
700*8975f5c5SAndroid Build Coastguard Worker 
701*8975f5c5SAndroid Build Coastguard Worker     template <typename ResourceType>
handleGennedResource(const gl::Context * context,ResourceType resourceID)702*8975f5c5SAndroid Build Coastguard Worker     void handleGennedResource(const gl::Context *context, ResourceType resourceID)
703*8975f5c5SAndroid Build Coastguard Worker     {
704*8975f5c5SAndroid Build Coastguard Worker         if (isCaptureActive())
705*8975f5c5SAndroid Build Coastguard Worker         {
706*8975f5c5SAndroid Build Coastguard Worker             ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
707*8975f5c5SAndroid Build Coastguard Worker             TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
708*8975f5c5SAndroid Build Coastguard Worker             tracker.setGennedResource(resourceID.value);
709*8975f5c5SAndroid Build Coastguard Worker         }
710*8975f5c5SAndroid Build Coastguard Worker     }
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker     template <typename ResourceType>
resourceIsGenerated(const gl::Context * context,ResourceType resourceID)713*8975f5c5SAndroid Build Coastguard Worker     bool resourceIsGenerated(const gl::Context *context, ResourceType resourceID)
714*8975f5c5SAndroid Build Coastguard Worker     {
715*8975f5c5SAndroid Build Coastguard Worker         ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
716*8975f5c5SAndroid Build Coastguard Worker         TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
717*8975f5c5SAndroid Build Coastguard Worker         return tracker.resourceIsGenerated(resourceID.value);
718*8975f5c5SAndroid Build Coastguard Worker     }
719*8975f5c5SAndroid Build Coastguard Worker 
720*8975f5c5SAndroid Build Coastguard Worker     template <typename ResourceType>
handleDeletedResource(const gl::Context * context,ResourceType resourceID)721*8975f5c5SAndroid Build Coastguard Worker     void handleDeletedResource(const gl::Context *context, ResourceType resourceID)
722*8975f5c5SAndroid Build Coastguard Worker     {
723*8975f5c5SAndroid Build Coastguard Worker         if (isCaptureActive())
724*8975f5c5SAndroid Build Coastguard Worker         {
725*8975f5c5SAndroid Build Coastguard Worker             ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
726*8975f5c5SAndroid Build Coastguard Worker             TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
727*8975f5c5SAndroid Build Coastguard Worker             tracker.setDeletedResource(resourceID.value);
728*8975f5c5SAndroid Build Coastguard Worker         }
729*8975f5c5SAndroid Build Coastguard Worker     }
730*8975f5c5SAndroid Build Coastguard Worker 
731*8975f5c5SAndroid Build Coastguard Worker     void *maybeGetShadowMemoryPointer(gl::Buffer *buffer, GLsizeiptr length, GLbitfield access);
732*8975f5c5SAndroid Build Coastguard Worker     void determineMemoryProtectionSupport(gl::Context *context);
733*8975f5c5SAndroid Build Coastguard Worker 
getFrameCaptureMutex()734*8975f5c5SAndroid Build Coastguard Worker     angle::SimpleMutex &getFrameCaptureMutex() { return mFrameCaptureMutex; }
735*8975f5c5SAndroid Build Coastguard Worker 
setDeferredLinkProgram(gl::ShaderProgramID programID)736*8975f5c5SAndroid Build Coastguard Worker     void setDeferredLinkProgram(gl::ShaderProgramID programID)
737*8975f5c5SAndroid Build Coastguard Worker     {
738*8975f5c5SAndroid Build Coastguard Worker         mDeferredLinkPrograms.emplace(programID);
739*8975f5c5SAndroid Build Coastguard Worker     }
isDeferredLinkProgram(gl::ShaderProgramID programID)740*8975f5c5SAndroid Build Coastguard Worker     bool isDeferredLinkProgram(gl::ShaderProgramID programID)
741*8975f5c5SAndroid Build Coastguard Worker     {
742*8975f5c5SAndroid Build Coastguard Worker         return (mDeferredLinkPrograms.find(programID) != mDeferredLinkPrograms.end());
743*8975f5c5SAndroid Build Coastguard Worker     }
744*8975f5c5SAndroid Build Coastguard Worker 
745*8975f5c5SAndroid Build Coastguard Worker   private:
746*8975f5c5SAndroid Build Coastguard Worker     void writeJSON(const gl::Context *context);
747*8975f5c5SAndroid Build Coastguard Worker     void writeCppReplayIndexFiles(const gl::Context *context, bool writeResetContextCall);
748*8975f5c5SAndroid Build Coastguard Worker     void writeMainContextCppReplay(const gl::Context *context,
749*8975f5c5SAndroid Build Coastguard Worker                                    const std::vector<CallCapture> &setupCalls,
750*8975f5c5SAndroid Build Coastguard Worker                                    StateResetHelper &StateResetHelper);
751*8975f5c5SAndroid Build Coastguard Worker 
752*8975f5c5SAndroid Build Coastguard Worker     void captureClientArraySnapshot(const gl::Context *context,
753*8975f5c5SAndroid Build Coastguard Worker                                     size_t vertexCount,
754*8975f5c5SAndroid Build Coastguard Worker                                     size_t instanceCount);
755*8975f5c5SAndroid Build Coastguard Worker     void captureMappedBufferSnapshot(const gl::Context *context, const CallCapture &call);
756*8975f5c5SAndroid Build Coastguard Worker 
757*8975f5c5SAndroid Build Coastguard Worker     void copyCompressedTextureData(const gl::Context *context, const CallCapture &call);
758*8975f5c5SAndroid Build Coastguard Worker     void captureCompressedTextureData(const gl::Context *context, const CallCapture &call);
759*8975f5c5SAndroid Build Coastguard Worker 
760*8975f5c5SAndroid Build Coastguard Worker     void reset();
761*8975f5c5SAndroid Build Coastguard Worker     void maybeOverrideEntryPoint(const gl::Context *context,
762*8975f5c5SAndroid Build Coastguard Worker                                  CallCapture &call,
763*8975f5c5SAndroid Build Coastguard Worker                                  std::vector<CallCapture> &newCalls);
764*8975f5c5SAndroid Build Coastguard Worker     void maybeCapturePreCallUpdates(const gl::Context *context,
765*8975f5c5SAndroid Build Coastguard Worker                                     CallCapture &call,
766*8975f5c5SAndroid Build Coastguard Worker                                     std::vector<CallCapture> *shareGroupSetupCalls,
767*8975f5c5SAndroid Build Coastguard Worker                                     ResourceIDToSetupCallsMap *resourceIDToSetupCalls);
768*8975f5c5SAndroid Build Coastguard Worker     template <typename ParamValueType>
769*8975f5c5SAndroid Build Coastguard Worker     void maybeGenResourceOnBind(const gl::Context *context, CallCapture &call);
770*8975f5c5SAndroid Build Coastguard Worker     void maybeCapturePostCallUpdates(const gl::Context *context);
771*8975f5c5SAndroid Build Coastguard Worker     void maybeCaptureDrawArraysClientData(const gl::Context *context,
772*8975f5c5SAndroid Build Coastguard Worker                                           CallCapture &call,
773*8975f5c5SAndroid Build Coastguard Worker                                           size_t instanceCount);
774*8975f5c5SAndroid Build Coastguard Worker     void maybeCaptureDrawElementsClientData(const gl::Context *context,
775*8975f5c5SAndroid Build Coastguard Worker                                             CallCapture &call,
776*8975f5c5SAndroid Build Coastguard Worker                                             size_t instanceCount);
777*8975f5c5SAndroid Build Coastguard Worker     void maybeCaptureCoherentBuffers(const gl::Context *context);
778*8975f5c5SAndroid Build Coastguard Worker     void captureCustomMapBufferFromContext(const gl::Context *context,
779*8975f5c5SAndroid Build Coastguard Worker                                            const char *entryPointName,
780*8975f5c5SAndroid Build Coastguard Worker                                            CallCapture &call,
781*8975f5c5SAndroid Build Coastguard Worker                                            std::vector<CallCapture> &callsOut);
782*8975f5c5SAndroid Build Coastguard Worker     void updateCopyImageSubData(CallCapture &call);
783*8975f5c5SAndroid Build Coastguard Worker     void overrideProgramBinary(const gl::Context *context,
784*8975f5c5SAndroid Build Coastguard Worker                                CallCapture &call,
785*8975f5c5SAndroid Build Coastguard Worker                                std::vector<CallCapture> &outCalls);
786*8975f5c5SAndroid Build Coastguard Worker     void updateResourceCountsFromParamCapture(const ParamCapture &param, ResourceIDType idType);
787*8975f5c5SAndroid Build Coastguard Worker     void updateResourceCountsFromCallCapture(const CallCapture &call);
788*8975f5c5SAndroid Build Coastguard Worker 
789*8975f5c5SAndroid Build Coastguard Worker     void runMidExecutionCapture(gl::Context *context);
790*8975f5c5SAndroid Build Coastguard Worker 
791*8975f5c5SAndroid Build Coastguard Worker     void scanSetupCalls(std::vector<CallCapture> &setupCalls);
792*8975f5c5SAndroid Build Coastguard Worker 
793*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> mFrameCalls;
794*8975f5c5SAndroid Build Coastguard Worker 
795*8975f5c5SAndroid Build Coastguard Worker     // We save one large buffer of binary data for the whole CPP replay.
796*8975f5c5SAndroid Build Coastguard Worker     // This simplifies a lot of file management.
797*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint8_t> mBinaryData;
798*8975f5c5SAndroid Build Coastguard Worker 
799*8975f5c5SAndroid Build Coastguard Worker     bool mEnabled;
800*8975f5c5SAndroid Build Coastguard Worker     bool mSerializeStateEnabled;
801*8975f5c5SAndroid Build Coastguard Worker     std::string mOutDirectory;
802*8975f5c5SAndroid Build Coastguard Worker     std::string mCaptureLabel;
803*8975f5c5SAndroid Build Coastguard Worker     bool mCompression;
804*8975f5c5SAndroid Build Coastguard Worker     gl::AttribArray<int> mClientVertexArrayMap;
805*8975f5c5SAndroid Build Coastguard Worker     uint32_t mFrameIndex;
806*8975f5c5SAndroid Build Coastguard Worker     uint32_t mCaptureStartFrame;
807*8975f5c5SAndroid Build Coastguard Worker     uint32_t mCaptureEndFrame;
808*8975f5c5SAndroid Build Coastguard Worker     bool mIsFirstFrame   = true;
809*8975f5c5SAndroid Build Coastguard Worker     bool mWroteIndexFile = false;
810*8975f5c5SAndroid Build Coastguard Worker     SurfaceParamsMap mDrawSurfaceParams;
811*8975f5c5SAndroid Build Coastguard Worker     gl::AttribArray<size_t> mClientArraySizes;
812*8975f5c5SAndroid Build Coastguard Worker     size_t mReadBufferSize;
813*8975f5c5SAndroid Build Coastguard Worker     size_t mResourceIDBufferSize;
814*8975f5c5SAndroid Build Coastguard Worker     HasResourceTypeMap mHasResourceType;
815*8975f5c5SAndroid Build Coastguard Worker     ResourceIDToSetupCallsMap mResourceIDToSetupCalls;
816*8975f5c5SAndroid Build Coastguard Worker     BufferDataMap mBufferDataMap;
817*8975f5c5SAndroid Build Coastguard Worker     bool mValidateSerializedState = false;
818*8975f5c5SAndroid Build Coastguard Worker     std::string mValidationExpression;
819*8975f5c5SAndroid Build Coastguard Worker     PackedEnumMap<ResourceIDType, uint32_t> mMaxAccessedResourceIDs;
820*8975f5c5SAndroid Build Coastguard Worker     CoherentBufferTracker mCoherentBufferTracker;
821*8975f5c5SAndroid Build Coastguard Worker     angle::SimpleMutex mFrameCaptureMutex;
822*8975f5c5SAndroid Build Coastguard Worker 
823*8975f5c5SAndroid Build Coastguard Worker     ResourceTracker mResourceTracker;
824*8975f5c5SAndroid Build Coastguard Worker     ReplayWriter mReplayWriter;
825*8975f5c5SAndroid Build Coastguard Worker 
826*8975f5c5SAndroid Build Coastguard Worker     // If you don't know which frame you want to start capturing at, use the capture trigger.
827*8975f5c5SAndroid Build Coastguard Worker     // Initialize it to the number of frames you want to capture, and then clear the value to 0 when
828*8975f5c5SAndroid Build Coastguard Worker     // you reach the content you want to capture. Currently only available on Android.
829*8975f5c5SAndroid Build Coastguard Worker     uint32_t mCaptureTrigger;
830*8975f5c5SAndroid Build Coastguard Worker 
831*8975f5c5SAndroid Build Coastguard Worker     bool mCaptureActive;
832*8975f5c5SAndroid Build Coastguard Worker     std::vector<uint32_t> mActiveFrameIndices;
833*8975f5c5SAndroid Build Coastguard Worker 
834*8975f5c5SAndroid Build Coastguard Worker     // Cache most recently compiled and linked sources.
835*8975f5c5SAndroid Build Coastguard Worker     ShaderSourceMap mCachedShaderSource;
836*8975f5c5SAndroid Build Coastguard Worker     ProgramSourceMap mCachedProgramSources;
837*8975f5c5SAndroid Build Coastguard Worker 
838*8975f5c5SAndroid Build Coastguard Worker     // Set of programs which were created but not linked before capture was started
839*8975f5c5SAndroid Build Coastguard Worker     std::set<gl::ShaderProgramID> mDeferredLinkPrograms;
840*8975f5c5SAndroid Build Coastguard Worker 
841*8975f5c5SAndroid Build Coastguard Worker     gl::ContextID mWindowSurfaceContextID;
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     std::vector<CallCapture> mShareGroupSetupCalls;
844*8975f5c5SAndroid Build Coastguard Worker     // Track which Contexts were created and made current at least once before MEC,
845*8975f5c5SAndroid Build Coastguard Worker     // requiring setup for replay
846*8975f5c5SAndroid Build Coastguard Worker     std::unordered_set<GLuint> mActiveContexts;
847*8975f5c5SAndroid Build Coastguard Worker 
848*8975f5c5SAndroid Build Coastguard Worker     // Invalid call counts per entry point while capture is active and inactive.
849*8975f5c5SAndroid Build Coastguard Worker     std::unordered_map<EntryPoint, size_t> mInvalidCallCountsActive;
850*8975f5c5SAndroid Build Coastguard Worker     std::unordered_map<EntryPoint, size_t> mInvalidCallCountsInactive;
851*8975f5c5SAndroid Build Coastguard Worker };
852*8975f5c5SAndroid Build Coastguard Worker 
853*8975f5c5SAndroid Build Coastguard Worker template <typename CaptureFuncT, typename... ArgsT>
CaptureGLCallToFrameCapture(CaptureFuncT captureFunc,bool isCallValid,gl::Context * context,ArgsT...captureParams)854*8975f5c5SAndroid Build Coastguard Worker void CaptureGLCallToFrameCapture(CaptureFuncT captureFunc,
855*8975f5c5SAndroid Build Coastguard Worker                                  bool isCallValid,
856*8975f5c5SAndroid Build Coastguard Worker                                  gl::Context *context,
857*8975f5c5SAndroid Build Coastguard Worker                                  ArgsT... captureParams)
858*8975f5c5SAndroid Build Coastguard Worker {
859*8975f5c5SAndroid Build Coastguard Worker     FrameCaptureShared *frameCaptureShared = context->getShareGroup()->getFrameCaptureShared();
860*8975f5c5SAndroid Build Coastguard Worker 
861*8975f5c5SAndroid Build Coastguard Worker     // EGL calls are protected by the global context mutex but only a subset of GL calls
862*8975f5c5SAndroid Build Coastguard Worker     // are so protected. Ensure FrameCaptureShared access thread safety by using a
863*8975f5c5SAndroid Build Coastguard Worker     // frame-capture only mutex.
864*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<angle::SimpleMutex> lock(frameCaptureShared->getFrameCaptureMutex());
865*8975f5c5SAndroid Build Coastguard Worker 
866*8975f5c5SAndroid Build Coastguard Worker     if (!frameCaptureShared->isCapturing())
867*8975f5c5SAndroid Build Coastguard Worker     {
868*8975f5c5SAndroid Build Coastguard Worker         return;
869*8975f5c5SAndroid Build Coastguard Worker     }
870*8975f5c5SAndroid Build Coastguard Worker 
871*8975f5c5SAndroid Build Coastguard Worker     CallCapture call = captureFunc(context->getState(), isCallValid, captureParams...);
872*8975f5c5SAndroid Build Coastguard Worker     frameCaptureShared->captureCall(context, std::move(call), isCallValid);
873*8975f5c5SAndroid Build Coastguard Worker }
874*8975f5c5SAndroid Build Coastguard Worker 
875*8975f5c5SAndroid Build Coastguard Worker template <typename FirstT, typename... OthersT>
GetEGLDisplayArg(FirstT display,OthersT...others)876*8975f5c5SAndroid Build Coastguard Worker egl::Display *GetEGLDisplayArg(FirstT display, OthersT... others)
877*8975f5c5SAndroid Build Coastguard Worker {
878*8975f5c5SAndroid Build Coastguard Worker     if constexpr (std::is_same<egl::Display *, FirstT>::value)
879*8975f5c5SAndroid Build Coastguard Worker     {
880*8975f5c5SAndroid Build Coastguard Worker         return display;
881*8975f5c5SAndroid Build Coastguard Worker     }
882*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
883*8975f5c5SAndroid Build Coastguard Worker }
884*8975f5c5SAndroid Build Coastguard Worker 
885*8975f5c5SAndroid Build Coastguard Worker template <typename CaptureFuncT, typename... ArgsT>
CaptureEGLCallToFrameCapture(CaptureFuncT captureFunc,bool isCallValid,egl::Thread * thread,ArgsT...captureParams)886*8975f5c5SAndroid Build Coastguard Worker void CaptureEGLCallToFrameCapture(CaptureFuncT captureFunc,
887*8975f5c5SAndroid Build Coastguard Worker                                   bool isCallValid,
888*8975f5c5SAndroid Build Coastguard Worker                                   egl::Thread *thread,
889*8975f5c5SAndroid Build Coastguard Worker                                   ArgsT... captureParams)
890*8975f5c5SAndroid Build Coastguard Worker {
891*8975f5c5SAndroid Build Coastguard Worker     gl::Context *context = thread->getContext();
892*8975f5c5SAndroid Build Coastguard Worker     if (!context)
893*8975f5c5SAndroid Build Coastguard Worker     {
894*8975f5c5SAndroid Build Coastguard Worker         // Get a valid context from the display argument if no context is associated with this
895*8975f5c5SAndroid Build Coastguard Worker         // thread
896*8975f5c5SAndroid Build Coastguard Worker         egl::Display *display = GetEGLDisplayArg(captureParams...);
897*8975f5c5SAndroid Build Coastguard Worker         if (display)
898*8975f5c5SAndroid Build Coastguard Worker         {
899*8975f5c5SAndroid Build Coastguard Worker             for (const auto &contextIter : display->getState().contextMap)
900*8975f5c5SAndroid Build Coastguard Worker             {
901*8975f5c5SAndroid Build Coastguard Worker                 context = contextIter.second;
902*8975f5c5SAndroid Build Coastguard Worker                 break;
903*8975f5c5SAndroid Build Coastguard Worker             }
904*8975f5c5SAndroid Build Coastguard Worker         }
905*8975f5c5SAndroid Build Coastguard Worker         if (!context)
906*8975f5c5SAndroid Build Coastguard Worker         {
907*8975f5c5SAndroid Build Coastguard Worker             return;
908*8975f5c5SAndroid Build Coastguard Worker         }
909*8975f5c5SAndroid Build Coastguard Worker     }
910*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<egl::ContextMutex> lock(context->getContextMutex());
911*8975f5c5SAndroid Build Coastguard Worker 
912*8975f5c5SAndroid Build Coastguard Worker     angle::FrameCaptureShared *frameCaptureShared =
913*8975f5c5SAndroid Build Coastguard Worker         context->getShareGroup()->getFrameCaptureShared();
914*8975f5c5SAndroid Build Coastguard Worker     if (!frameCaptureShared->isCapturing())
915*8975f5c5SAndroid Build Coastguard Worker     {
916*8975f5c5SAndroid Build Coastguard Worker         return;
917*8975f5c5SAndroid Build Coastguard Worker     }
918*8975f5c5SAndroid Build Coastguard Worker 
919*8975f5c5SAndroid Build Coastguard Worker     angle::CallCapture call = captureFunc(thread, isCallValid, captureParams...);
920*8975f5c5SAndroid Build Coastguard Worker     frameCaptureShared->captureCall(context, std::move(call), true);
921*8975f5c5SAndroid Build Coastguard Worker }
922*8975f5c5SAndroid Build Coastguard Worker 
923*8975f5c5SAndroid Build Coastguard Worker // Pointer capture helpers.
924*8975f5c5SAndroid Build Coastguard Worker void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture);
925*8975f5c5SAndroid Build Coastguard Worker void CaptureString(const GLchar *str, ParamCapture *paramCapture);
926*8975f5c5SAndroid Build Coastguard Worker void CaptureStringLimit(const GLchar *str, uint32_t limit, ParamCapture *paramCapture);
927*8975f5c5SAndroid Build Coastguard Worker void CaptureVertexPointerGLES1(const gl::State &glState,
928*8975f5c5SAndroid Build Coastguard Worker                                gl::ClientVertexArrayType type,
929*8975f5c5SAndroid Build Coastguard Worker                                const void *pointer,
930*8975f5c5SAndroid Build Coastguard Worker                                ParamCapture *paramCapture);
931*8975f5c5SAndroid Build Coastguard Worker 
932*8975f5c5SAndroid Build Coastguard Worker gl::Program *GetProgramForCapture(const gl::State &glState, gl::ShaderProgramID handle);
933*8975f5c5SAndroid Build Coastguard Worker 
934*8975f5c5SAndroid Build Coastguard Worker // For GetIntegerv, GetFloatv, etc.
935*8975f5c5SAndroid Build Coastguard Worker void CaptureGetParameter(const gl::State &glState,
936*8975f5c5SAndroid Build Coastguard Worker                          GLenum pname,
937*8975f5c5SAndroid Build Coastguard Worker                          size_t typeSize,
938*8975f5c5SAndroid Build Coastguard Worker                          ParamCapture *paramCapture);
939*8975f5c5SAndroid Build Coastguard Worker 
940*8975f5c5SAndroid Build Coastguard Worker void CaptureGetActiveUniformBlockivParameters(const gl::State &glState,
941*8975f5c5SAndroid Build Coastguard Worker                                               gl::ShaderProgramID handle,
942*8975f5c5SAndroid Build Coastguard Worker                                               gl::UniformBlockIndex uniformBlockIndex,
943*8975f5c5SAndroid Build Coastguard Worker                                               GLenum pname,
944*8975f5c5SAndroid Build Coastguard Worker                                               ParamCapture *paramCapture);
945*8975f5c5SAndroid Build Coastguard Worker 
946*8975f5c5SAndroid Build Coastguard Worker template <typename T>
CaptureClearBufferValue(GLenum buffer,const T * value,ParamCapture * paramCapture)947*8975f5c5SAndroid Build Coastguard Worker void CaptureClearBufferValue(GLenum buffer, const T *value, ParamCapture *paramCapture)
948*8975f5c5SAndroid Build Coastguard Worker {
949*8975f5c5SAndroid Build Coastguard Worker     // Per the spec, color buffers have a vec4, the rest a single value
950*8975f5c5SAndroid Build Coastguard Worker     uint32_t valueSize = (buffer == GL_COLOR) ? 4 : 1;
951*8975f5c5SAndroid Build Coastguard Worker     CaptureMemory(value, valueSize * sizeof(T), paramCapture);
952*8975f5c5SAndroid Build Coastguard Worker }
953*8975f5c5SAndroid Build Coastguard Worker 
954*8975f5c5SAndroid Build Coastguard Worker void CaptureGenHandlesImpl(GLsizei n, GLuint *handles, ParamCapture *paramCapture);
955*8975f5c5SAndroid Build Coastguard Worker 
956*8975f5c5SAndroid Build Coastguard Worker template <typename T>
CaptureGenHandles(GLsizei n,T * handles,ParamCapture * paramCapture)957*8975f5c5SAndroid Build Coastguard Worker void CaptureGenHandles(GLsizei n, T *handles, ParamCapture *paramCapture)
958*8975f5c5SAndroid Build Coastguard Worker {
959*8975f5c5SAndroid Build Coastguard Worker     paramCapture->dataNElements = n;
960*8975f5c5SAndroid Build Coastguard Worker     CaptureGenHandlesImpl(n, reinterpret_cast<GLuint *>(handles), paramCapture);
961*8975f5c5SAndroid Build Coastguard Worker }
962*8975f5c5SAndroid Build Coastguard Worker 
963*8975f5c5SAndroid Build Coastguard Worker template <typename T>
CaptureArray(T * elements,GLsizei n,ParamCapture * paramCapture)964*8975f5c5SAndroid Build Coastguard Worker void CaptureArray(T *elements, GLsizei n, ParamCapture *paramCapture)
965*8975f5c5SAndroid Build Coastguard Worker {
966*8975f5c5SAndroid Build Coastguard Worker     paramCapture->dataNElements = n;
967*8975f5c5SAndroid Build Coastguard Worker     CaptureMemory(elements, n * sizeof(T), paramCapture);
968*8975f5c5SAndroid Build Coastguard Worker }
969*8975f5c5SAndroid Build Coastguard Worker 
970*8975f5c5SAndroid Build Coastguard Worker void CaptureShaderStrings(GLsizei count,
971*8975f5c5SAndroid Build Coastguard Worker                           const GLchar *const *strings,
972*8975f5c5SAndroid Build Coastguard Worker                           const GLint *length,
973*8975f5c5SAndroid Build Coastguard Worker                           ParamCapture *paramCapture);
974*8975f5c5SAndroid Build Coastguard Worker 
975*8975f5c5SAndroid Build Coastguard Worker bool IsTrackedPerContext(ResourceIDType type);
976*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
977*8975f5c5SAndroid Build Coastguard Worker 
978*8975f5c5SAndroid Build Coastguard Worker template <typename T>
CaptureTextureAndSamplerParameter_params(GLenum pname,const T * param,angle::ParamCapture * paramCapture)979*8975f5c5SAndroid Build Coastguard Worker void CaptureTextureAndSamplerParameter_params(GLenum pname,
980*8975f5c5SAndroid Build Coastguard Worker                                               const T *param,
981*8975f5c5SAndroid Build Coastguard Worker                                               angle::ParamCapture *paramCapture)
982*8975f5c5SAndroid Build Coastguard Worker {
983*8975f5c5SAndroid Build Coastguard Worker     if (pname == GL_TEXTURE_BORDER_COLOR || pname == GL_TEXTURE_CROP_RECT_OES)
984*8975f5c5SAndroid Build Coastguard Worker     {
985*8975f5c5SAndroid Build Coastguard Worker         CaptureMemory(param, sizeof(T) * 4, paramCapture);
986*8975f5c5SAndroid Build Coastguard Worker     }
987*8975f5c5SAndroid Build Coastguard Worker     else
988*8975f5c5SAndroid Build Coastguard Worker     {
989*8975f5c5SAndroid Build Coastguard Worker         CaptureMemory(param, sizeof(T), paramCapture);
990*8975f5c5SAndroid Build Coastguard Worker     }
991*8975f5c5SAndroid Build Coastguard Worker }
992*8975f5c5SAndroid Build Coastguard Worker 
993*8975f5c5SAndroid Build Coastguard Worker namespace egl
994*8975f5c5SAndroid Build Coastguard Worker {
995*8975f5c5SAndroid Build Coastguard Worker angle::ParamCapture CaptureAttributeMap(const egl::AttributeMap &attribMap);
996*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
997*8975f5c5SAndroid Build Coastguard Worker 
998*8975f5c5SAndroid Build Coastguard Worker #endif  // LIBANGLE_FRAME_CAPTURE_H_
999