• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 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 // serialize.cpp:
7 //   ANGLE GL state serialization.
8 //
9 
10 #include "libANGLE/capture/serialize.h"
11 
12 #include "common/Color.h"
13 #include "common/MemoryBuffer.h"
14 #include "common/angleutils.h"
15 #include "common/gl_enum_utils.h"
16 #include "common/serializer/JsonSerializer.h"
17 #include "libANGLE/Buffer.h"
18 #include "libANGLE/Caps.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/Framebuffer.h"
21 #include "libANGLE/Query.h"
22 #include "libANGLE/RefCountObject.h"
23 #include "libANGLE/ResourceMap.h"
24 #include "libANGLE/Sampler.h"
25 #include "libANGLE/State.h"
26 #include "libANGLE/TransformFeedback.h"
27 #include "libANGLE/VertexAttribute.h"
28 #include "libANGLE/angletypes.h"
29 #include "libANGLE/renderer/FramebufferImpl.h"
30 #include "libANGLE/renderer/RenderbufferImpl.h"
31 
32 #include <vector>
33 
34 #if !ANGLE_CAPTURE_ENABLED
35 #    error Frame capture must be enabled to build this file.
36 #endif  // !ANGLE_CAPTURE_ENABLED
37 
38 // Note: when diagnosing serialization comparison failures, you can disable the unused function
39 // compiler warning to allow bisecting the comparison function. One first check is to disable
40 // Framebuffer Attachment pixel comparison which includes the pixel contents of the default FBO.
41 // ANGLE_DISABLE_UNUSED_FUNCTION_WARNING
42 
43 namespace angle
44 {
45 namespace
46 {
47 template <typename ArgT>
ToString(const ArgT & arg)48 std::string ToString(const ArgT &arg)
49 {
50     std::ostringstream strstr;
51     strstr << arg;
52     return strstr.str();
53 }
54 
55 #define ENUM_TO_STRING(C, M) \
56     case C ::M:              \
57         return #M
58 
InitStateToString(gl::InitState state)59 const char *InitStateToString(gl::InitState state)
60 {
61     switch (state)
62     {
63         ENUM_TO_STRING(gl::InitState, Initialized);
64         ENUM_TO_STRING(gl::InitState, MayNeedInit);
65         default:
66             return "invalid";
67     }
68 }
69 
SrgbOverrideToString(gl::SrgbOverride value)70 const char *SrgbOverrideToString(gl::SrgbOverride value)
71 {
72     switch (value)
73     {
74         ENUM_TO_STRING(gl::SrgbOverride, Default);
75         ENUM_TO_STRING(gl::SrgbOverride, SRGB);
76         ENUM_TO_STRING(gl::SrgbOverride, Linear);
77         default:
78             return "invalid";
79     }
80 }
81 
ColorGenericTypeToString(gl::ColorGeneric::Type type)82 const char *ColorGenericTypeToString(gl::ColorGeneric::Type type)
83 {
84     switch (type)
85     {
86         ENUM_TO_STRING(gl::ColorGeneric::Type, Float);
87         ENUM_TO_STRING(gl::ColorGeneric::Type, Int);
88         ENUM_TO_STRING(gl::ColorGeneric::Type, UInt);
89         default:
90             return "invalid";
91     }
92 }
93 
CompileStatusToString(gl::CompileStatus status)94 const char *CompileStatusToString(gl::CompileStatus status)
95 {
96     switch (status)
97     {
98         ENUM_TO_STRING(gl::CompileStatus, NOT_COMPILED);
99         ENUM_TO_STRING(gl::CompileStatus, COMPILE_REQUESTED);
100         ENUM_TO_STRING(gl::CompileStatus, COMPILED);
101         default:
102             return "invalid";
103     }
104 }
105 
106 #undef ENUM_TO_STRING
107 
108 class [[nodiscard]] GroupScope
109 {
110   public:
GroupScope(JsonSerializer * json,const std::string & name)111     GroupScope(JsonSerializer *json, const std::string &name) : mJson(json)
112     {
113         mJson->startGroup(name);
114     }
115 
GroupScope(JsonSerializer * json,const std::string & name,int index)116     GroupScope(JsonSerializer *json, const std::string &name, int index) : mJson(json)
117     {
118         constexpr size_t kBufSize = 255;
119         char buf[kBufSize + 1]    = {};
120         snprintf(buf, kBufSize, "%s%s%03d", name.c_str(), name.empty() ? "" : " ", index);
121         mJson->startGroup(buf);
122     }
123 
GroupScope(JsonSerializer * json,int index)124     GroupScope(JsonSerializer *json, int index) : GroupScope(json, "", index) {}
125 
~GroupScope()126     ~GroupScope() { mJson->endGroup(); }
127 
128   private:
129     JsonSerializer *mJson;
130 };
131 
SerializeColorF(JsonSerializer * json,const ColorF & color)132 void SerializeColorF(JsonSerializer *json, const ColorF &color)
133 {
134     json->addScalar("red", color.red);
135     json->addScalar("green", color.green);
136     json->addScalar("blue", color.blue);
137     json->addScalar("alpha", color.alpha);
138 }
139 
SerializeColorFWithGroup(JsonSerializer * json,const char * groupName,const ColorF & color)140 void SerializeColorFWithGroup(JsonSerializer *json, const char *groupName, const ColorF &color)
141 {
142     GroupScope group(json, groupName);
143     SerializeColorF(json, color);
144 }
145 
SerializeColorI(JsonSerializer * json,const ColorI & color)146 void SerializeColorI(JsonSerializer *json, const ColorI &color)
147 {
148     json->addScalar("Red", color.red);
149     json->addScalar("Green", color.green);
150     json->addScalar("Blue", color.blue);
151     json->addScalar("Alpha", color.alpha);
152 }
153 
SerializeColorUI(JsonSerializer * json,const ColorUI & color)154 void SerializeColorUI(JsonSerializer *json, const ColorUI &color)
155 {
156     json->addScalar("Red", color.red);
157     json->addScalar("Green", color.green);
158     json->addScalar("Blue", color.blue);
159     json->addScalar("Alpha", color.alpha);
160 }
161 
SerializeExtents(JsonSerializer * json,const gl::Extents & extents)162 void SerializeExtents(JsonSerializer *json, const gl::Extents &extents)
163 {
164     json->addScalar("Width", extents.width);
165     json->addScalar("Height", extents.height);
166     json->addScalar("Depth", extents.depth);
167 }
168 
169 template <class ObjectType>
SerializeOffsetBindingPointerVector(JsonSerializer * json,const char * groupName,const std::vector<gl::OffsetBindingPointer<ObjectType>> & offsetBindingPointerVector)170 void SerializeOffsetBindingPointerVector(
171     JsonSerializer *json,
172     const char *groupName,
173     const std::vector<gl::OffsetBindingPointer<ObjectType>> &offsetBindingPointerVector)
174 {
175     GroupScope vectorGroup(json, groupName);
176 
177     for (size_t i = 0; i < offsetBindingPointerVector.size(); i++)
178     {
179         GroupScope itemGroup(json, static_cast<int>(i));
180         json->addScalar("Value", offsetBindingPointerVector[i].id().value);
181         json->addScalar("Offset", offsetBindingPointerVector[i].getOffset());
182         json->addScalar("Size", offsetBindingPointerVector[i].getSize());
183     }
184 }
185 
186 template <class ObjectType>
SerializeBindingPointerVector(JsonSerializer * json,const std::vector<gl::BindingPointer<ObjectType>> & bindingPointerVector)187 void SerializeBindingPointerVector(
188     JsonSerializer *json,
189     const std::vector<gl::BindingPointer<ObjectType>> &bindingPointerVector)
190 {
191     for (size_t i = 0; i < bindingPointerVector.size(); i++)
192     {
193         const gl::BindingPointer<ObjectType> &obj = bindingPointerVector[i];
194 
195         // Do not serialize zero bindings, as this will create unwanted diffs
196         if (obj.id().value != 0)
197         {
198             std::ostringstream s;
199             s << std::setfill('0') << std::setw(3) << i;
200             json->addScalar(s.str().c_str(), obj.id().value);
201         }
202     }
203 }
204 
205 template <class T>
SerializeRange(JsonSerializer * json,const gl::Range<T> & range)206 void SerializeRange(JsonSerializer *json, const gl::Range<T> &range)
207 {
208     GroupScope group(json, "Range");
209     json->addScalar("Low", range.low());
210     json->addScalar("High", range.high());
211 }
212 
IsValidColorAttachmentBinding(GLenum binding,size_t colorAttachmentsCount)213 bool IsValidColorAttachmentBinding(GLenum binding, size_t colorAttachmentsCount)
214 {
215     return binding == GL_BACK || (binding >= GL_COLOR_ATTACHMENT0 &&
216                                   (binding - GL_COLOR_ATTACHMENT0) < colorAttachmentsCount);
217 }
218 
SerializeFormat(JsonSerializer * json,GLenum glFormat)219 void SerializeFormat(JsonSerializer *json, GLenum glFormat)
220 {
221     json->addCString("InternalFormat", gl::GLenumToString(gl::GLESEnum::InternalFormat, glFormat));
222 }
223 
SerializeInternalFormat(JsonSerializer * json,const gl::InternalFormat * internalFormat)224 void SerializeInternalFormat(JsonSerializer *json, const gl::InternalFormat *internalFormat)
225 {
226     SerializeFormat(json, internalFormat->internalFormat);
227 }
228 
SerializeANGLEFormat(JsonSerializer * json,const angle::Format * format)229 void SerializeANGLEFormat(JsonSerializer *json, const angle::Format *format)
230 {
231     SerializeFormat(json, format->glInternalFormat);
232 }
233 
SerializeGLFormat(JsonSerializer * json,const gl::Format & format)234 void SerializeGLFormat(JsonSerializer *json, const gl::Format &format)
235 {
236     SerializeInternalFormat(json, format.info);
237 }
238 
ReadPixelsFromAttachment(const gl::Context * context,gl::Framebuffer * framebuffer,const gl::FramebufferAttachment & framebufferAttachment,ScratchBuffer * scratchBuffer,MemoryBuffer ** pixels)239 Result ReadPixelsFromAttachment(const gl::Context *context,
240                                 gl::Framebuffer *framebuffer,
241                                 const gl::FramebufferAttachment &framebufferAttachment,
242                                 ScratchBuffer *scratchBuffer,
243                                 MemoryBuffer **pixels)
244 {
245     gl::Extents extents       = framebufferAttachment.getSize();
246     GLenum binding            = framebufferAttachment.getBinding();
247     gl::InternalFormat format = *framebufferAttachment.getFormat().info;
248     if (IsValidColorAttachmentBinding(binding,
249                                       framebuffer->getState().getColorAttachments().size()))
250     {
251         format = framebuffer->getImplementation()->getImplementationColorReadFormat(context);
252     }
253     ANGLE_CHECK_GL_ALLOC(const_cast<gl::Context *>(context),
254                          scratchBuffer->getInitialized(
255                              format.pixelBytes * extents.width * extents.height, pixels, 0));
256     ANGLE_TRY(framebuffer->readPixels(context, gl::Rectangle{0, 0, extents.width, extents.height},
257                                       format.format, format.type, gl::PixelPackState{}, nullptr,
258                                       (*pixels)->data()));
259     return Result::Continue;
260 }
SerializeImageIndex(JsonSerializer * json,const gl::ImageIndex & imageIndex)261 void SerializeImageIndex(JsonSerializer *json, const gl::ImageIndex &imageIndex)
262 {
263     GroupScope group(json, "Image");
264     json->addString("ImageType", ToString(imageIndex.getType()));
265     json->addScalar("LevelIndex", imageIndex.getLevelIndex());
266     json->addScalar("LayerIndex", imageIndex.getLayerIndex());
267     json->addScalar("LayerCount", imageIndex.getLayerCount());
268 }
269 
SerializeFramebufferAttachment(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Framebuffer * framebuffer,const gl::FramebufferAttachment & framebufferAttachment,gl::GLESEnum enumGroup)270 Result SerializeFramebufferAttachment(const gl::Context *context,
271                                       JsonSerializer *json,
272                                       ScratchBuffer *scratchBuffer,
273                                       gl::Framebuffer *framebuffer,
274                                       const gl::FramebufferAttachment &framebufferAttachment,
275                                       gl::GLESEnum enumGroup)
276 {
277     if (framebufferAttachment.type() == GL_TEXTURE ||
278         framebufferAttachment.type() == GL_RENDERBUFFER)
279     {
280         json->addScalar("AttachedResourceID", framebufferAttachment.id());
281     }
282     json->addCString(
283         "Type", gl::GLenumToString(gl::GLESEnum::ObjectIdentifier, framebufferAttachment.type()));
284     // serialize target variable
285     json->addString("Binding", gl::GLenumToString(enumGroup, framebufferAttachment.getBinding()));
286     if (framebufferAttachment.type() == GL_TEXTURE)
287     {
288         SerializeImageIndex(json, framebufferAttachment.getTextureImageIndex());
289     }
290     json->addScalar("NumViews", framebufferAttachment.getNumViews());
291     json->addScalar("Multiview", framebufferAttachment.isMultiview());
292     json->addScalar("ViewIndex", framebufferAttachment.getBaseViewIndex());
293     json->addScalar("Samples", framebufferAttachment.getRenderToTextureSamples());
294 
295     {
296         GroupScope extentsGroup(json, "Extents");
297         SerializeExtents(json, framebufferAttachment.getSize());
298     }
299 
300     if (framebufferAttachment.type() != GL_TEXTURE &&
301         framebufferAttachment.type() != GL_RENDERBUFFER)
302     {
303         GLenum prevReadBufferState = framebuffer->getReadBufferState();
304         GLenum binding             = framebufferAttachment.getBinding();
305         if (IsValidColorAttachmentBinding(binding,
306                                           framebuffer->getState().getColorAttachments().size()))
307         {
308             framebuffer->setReadBuffer(framebufferAttachment.getBinding());
309             ANGLE_TRY(framebuffer->syncState(context, GL_FRAMEBUFFER, gl::Command::Other));
310         }
311 
312         if (framebufferAttachment.initState() == gl::InitState::Initialized)
313         {
314             MemoryBuffer *pixelsPtr = nullptr;
315             ANGLE_TRY(ReadPixelsFromAttachment(context, framebuffer, framebufferAttachment,
316                                                scratchBuffer, &pixelsPtr));
317             json->addBlob("Data", pixelsPtr->data(), pixelsPtr->size());
318         }
319         else
320         {
321             json->addCString("Data", "Not initialized");
322         }
323         // Reset framebuffer state
324         framebuffer->setReadBuffer(prevReadBufferState);
325     }
326     return Result::Continue;
327 }
328 
SerializeFramebufferState(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Framebuffer * framebuffer,const gl::FramebufferState & framebufferState)329 Result SerializeFramebufferState(const gl::Context *context,
330                                  JsonSerializer *json,
331                                  ScratchBuffer *scratchBuffer,
332                                  gl::Framebuffer *framebuffer,
333                                  const gl::FramebufferState &framebufferState)
334 {
335     GroupScope group(json, "Framebuffer", framebufferState.id().value);
336 
337     json->addString("Label", framebufferState.getLabel());
338     json->addVector("DrawStates", framebufferState.getDrawBufferStates());
339     json->addScalar("ReadBufferState", framebufferState.getReadBufferState());
340     json->addScalar("DefaultWidth", framebufferState.getDefaultWidth());
341     json->addScalar("DefaultHeight", framebufferState.getDefaultHeight());
342     json->addScalar("DefaultSamples", framebufferState.getDefaultSamples());
343     json->addScalar("DefaultFixedSampleLocation",
344                     framebufferState.getDefaultFixedSampleLocations());
345     json->addScalar("DefaultLayers", framebufferState.getDefaultLayers());
346     json->addScalar("FlipY", framebufferState.getFlipY());
347 
348     {
349         GroupScope attachmentsGroup(json, "Attachments");
350         const gl::DrawBuffersVector<gl::FramebufferAttachment> &colorAttachments =
351             framebufferState.getColorAttachments();
352         for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size();
353              ++attachmentIndex)
354         {
355             const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex];
356             if (colorAttachment.isAttached())
357             {
358                 GroupScope colorAttachmentgroup(json, "ColorAttachment",
359                                                 static_cast<int>(attachmentIndex));
360                 ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
361                                                          colorAttachment,
362                                                          gl::GLESEnum::ColorBuffer));
363             }
364         }
365         if (framebuffer->getDepthStencilAttachment())
366         {
367             GroupScope dsAttachmentgroup(json, "DepthStencilAttachment");
368             ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
369                                                      *framebuffer->getDepthStencilAttachment(),
370                                                      gl::GLESEnum::AllEnums));
371         }
372         else
373         {
374             if (framebuffer->getDepthAttachment())
375             {
376                 GroupScope depthAttachmentgroup(json, "DepthAttachment");
377                 ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
378                                                          *framebuffer->getDepthAttachment(),
379                                                          gl::GLESEnum::FramebufferAttachment));
380             }
381             if (framebuffer->getStencilAttachment())
382             {
383                 GroupScope stencilAttachmengroup(json, "StencilAttachment");
384                 ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
385                                                          *framebuffer->getStencilAttachment(),
386                                                          gl::GLESEnum::AllEnums));
387             }
388         }
389     }
390     return Result::Continue;
391 }
392 
SerializeFramebuffer(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Framebuffer * framebuffer)393 Result SerializeFramebuffer(const gl::Context *context,
394                             JsonSerializer *json,
395                             ScratchBuffer *scratchBuffer,
396                             gl::Framebuffer *framebuffer)
397 {
398     return SerializeFramebufferState(context, json, scratchBuffer, framebuffer,
399                                      framebuffer->getState());
400 }
401 
SerializeRasterizerState(JsonSerializer * json,const gl::RasterizerState & rasterizerState)402 void SerializeRasterizerState(JsonSerializer *json, const gl::RasterizerState &rasterizerState)
403 {
404     GroupScope group(json, "Rasterizer");
405     json->addScalar("CullFace", rasterizerState.cullFace);
406     json->addString("CullMode", ToString(rasterizerState.cullMode));
407     json->addScalar("FrontFace", rasterizerState.frontFace);
408     json->addString("PolygonMode", ToString(rasterizerState.polygonMode));
409     json->addScalar("PolygonOffsetPoint", rasterizerState.polygonOffsetPoint);
410     json->addScalar("PolygonOffsetLine", rasterizerState.polygonOffsetLine);
411     json->addScalar("PolygonOffsetFill", rasterizerState.polygonOffsetFill);
412     json->addScalar("PolygonOffsetFactor", rasterizerState.polygonOffsetFactor);
413     json->addScalar("PolygonOffsetUnits", rasterizerState.polygonOffsetUnits);
414     json->addScalar("PolygonOffsetClamp", rasterizerState.polygonOffsetClamp);
415     json->addScalar("DepthClamp", rasterizerState.depthClamp);
416     json->addScalar("PointDrawMode", rasterizerState.pointDrawMode);
417     json->addScalar("MultiSample", rasterizerState.multiSample);
418     json->addScalar("RasterizerDiscard", rasterizerState.rasterizerDiscard);
419     json->addScalar("Dither", rasterizerState.dither);
420 }
421 
SerializeRectangle(JsonSerializer * json,const std::string & name,const gl::Rectangle & rectangle)422 void SerializeRectangle(JsonSerializer *json,
423                         const std::string &name,
424                         const gl::Rectangle &rectangle)
425 {
426     GroupScope group(json, name);
427     json->addScalar("x", rectangle.x);
428     json->addScalar("y", rectangle.y);
429     json->addScalar("w", rectangle.width);
430     json->addScalar("h", rectangle.height);
431 }
432 
SerializeBlendStateExt(JsonSerializer * json,const gl::BlendStateExt & blendStateExt)433 void SerializeBlendStateExt(JsonSerializer *json, const gl::BlendStateExt &blendStateExt)
434 {
435     GroupScope group(json, "BlendStateExt");
436     json->addScalar("DrawBufferCount", blendStateExt.getDrawBufferCount());
437     json->addScalar("EnableMask", blendStateExt.getEnabledMask().bits());
438     json->addScalar("DstColor", blendStateExt.getDstColorBits());
439     json->addScalar("DstAlpha", blendStateExt.getDstAlphaBits());
440     json->addScalar("SrcColor", blendStateExt.getSrcColorBits());
441     json->addScalar("SrcAlpha", blendStateExt.getSrcAlphaBits());
442     json->addScalar("EquationColor", blendStateExt.getEquationColorBits());
443     json->addScalar("EquationAlpha", blendStateExt.getEquationAlphaBits());
444     json->addScalar("ColorMask", blendStateExt.getColorMaskBits());
445 }
446 
SerializeDepthStencilState(JsonSerializer * json,const gl::DepthStencilState & depthStencilState)447 void SerializeDepthStencilState(JsonSerializer *json,
448                                 const gl::DepthStencilState &depthStencilState)
449 {
450     GroupScope group(json, "DepthStencilState");
451     json->addScalar("DepthTest", depthStencilState.depthTest);
452     json->addScalar("DepthFunc", depthStencilState.depthFunc);
453     json->addScalar("DepthMask", depthStencilState.depthMask);
454     json->addScalar("StencilTest", depthStencilState.stencilTest);
455     json->addScalar("StencilFunc", depthStencilState.stencilFunc);
456     json->addScalar("StencilMask", depthStencilState.stencilMask);
457     json->addScalar("StencilFail", depthStencilState.stencilFail);
458     json->addScalar("StencilPassDepthFail", depthStencilState.stencilPassDepthFail);
459     json->addScalar("StencilPassDepthPass", depthStencilState.stencilPassDepthPass);
460     json->addScalar("StencilWritemask", depthStencilState.stencilWritemask);
461     json->addScalar("StencilBackFunc", depthStencilState.stencilBackFunc);
462     json->addScalar("StencilBackMask", depthStencilState.stencilBackMask);
463     json->addScalar("StencilBackFail", depthStencilState.stencilBackFail);
464     json->addScalar("StencilBackPassDepthFail", depthStencilState.stencilBackPassDepthFail);
465     json->addScalar("StencilBackPassDepthPass", depthStencilState.stencilBackPassDepthPass);
466     json->addScalar("StencilBackWritemask", depthStencilState.stencilBackWritemask);
467 }
468 
SerializeVertexAttribCurrentValueData(JsonSerializer * json,const gl::VertexAttribCurrentValueData & vertexAttribCurrentValueData)469 void SerializeVertexAttribCurrentValueData(
470     JsonSerializer *json,
471     const gl::VertexAttribCurrentValueData &vertexAttribCurrentValueData)
472 {
473     ASSERT(vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float ||
474            vertexAttribCurrentValueData.Type == gl::VertexAttribType::Int ||
475            vertexAttribCurrentValueData.Type == gl::VertexAttribType::UnsignedInt);
476     if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float)
477     {
478         json->addScalar("0", vertexAttribCurrentValueData.Values.FloatValues[0]);
479         json->addScalar("1", vertexAttribCurrentValueData.Values.FloatValues[1]);
480         json->addScalar("2", vertexAttribCurrentValueData.Values.FloatValues[2]);
481         json->addScalar("3", vertexAttribCurrentValueData.Values.FloatValues[3]);
482     }
483     else if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Int)
484     {
485         json->addScalar("0", vertexAttribCurrentValueData.Values.IntValues[0]);
486         json->addScalar("1", vertexAttribCurrentValueData.Values.IntValues[1]);
487         json->addScalar("2", vertexAttribCurrentValueData.Values.IntValues[2]);
488         json->addScalar("3", vertexAttribCurrentValueData.Values.IntValues[3]);
489     }
490     else
491     {
492         json->addScalar("0", vertexAttribCurrentValueData.Values.UnsignedIntValues[0]);
493         json->addScalar("1", vertexAttribCurrentValueData.Values.UnsignedIntValues[1]);
494         json->addScalar("2", vertexAttribCurrentValueData.Values.UnsignedIntValues[2]);
495         json->addScalar("3", vertexAttribCurrentValueData.Values.UnsignedIntValues[3]);
496     }
497 }
498 
SerializePixelPackState(JsonSerializer * json,const gl::PixelPackState & pixelPackState)499 void SerializePixelPackState(JsonSerializer *json, const gl::PixelPackState &pixelPackState)
500 {
501     GroupScope group(json, "PixelPackState");
502     json->addScalar("Alignment", pixelPackState.alignment);
503     json->addScalar("RowLength", pixelPackState.rowLength);
504     json->addScalar("SkipRows", pixelPackState.skipRows);
505     json->addScalar("SkipPixels", pixelPackState.skipPixels);
506     json->addScalar("ImageHeight", pixelPackState.imageHeight);
507     json->addScalar("SkipImages", pixelPackState.skipImages);
508     json->addScalar("ReverseRowOrder", pixelPackState.reverseRowOrder);
509 }
510 
SerializePixelUnpackState(JsonSerializer * json,const gl::PixelUnpackState & pixelUnpackState)511 void SerializePixelUnpackState(JsonSerializer *json, const gl::PixelUnpackState &pixelUnpackState)
512 {
513     GroupScope group(json, "PixelUnpackState");
514     json->addScalar("Alignment", pixelUnpackState.alignment);
515     json->addScalar("RowLength", pixelUnpackState.rowLength);
516     json->addScalar("SkipRows", pixelUnpackState.skipRows);
517     json->addScalar("SkipPixels", pixelUnpackState.skipPixels);
518     json->addScalar("ImageHeight", pixelUnpackState.imageHeight);
519     json->addScalar("SkipImages", pixelUnpackState.skipImages);
520 }
521 
SerializeImageUnit(JsonSerializer * json,const gl::ImageUnit & imageUnit,int imageUnitIndex)522 void SerializeImageUnit(JsonSerializer *json, const gl::ImageUnit &imageUnit, int imageUnitIndex)
523 {
524     GroupScope group(json, "ImageUnit", imageUnitIndex);
525     json->addScalar("Level", imageUnit.level);
526     json->addScalar("Layered", imageUnit.layered);
527     json->addScalar("Layer", imageUnit.layer);
528     json->addScalar("Access", imageUnit.access);
529     json->addCString("Format", gl::GLinternalFormatToString(imageUnit.format));
530     json->addScalar("TextureID", imageUnit.texture.id().value);
531 }
532 
533 template <typename ResourceType>
SerializeResourceID(JsonSerializer * json,const char * name,const ResourceType * resource)534 void SerializeResourceID(JsonSerializer *json, const char *name, const ResourceType *resource)
535 {
536     json->addScalar(name, resource ? resource->id().value : 0);
537 }
538 
SerializeContextState(JsonSerializer * json,const gl::State & state)539 void SerializeContextState(JsonSerializer *json, const gl::State &state)
540 {
541     GroupScope group(json, "ContextState");
542     json->addScalar("ClientType", state.getClientType());
543     json->addScalar("Priority", state.getContextPriority());
544     json->addScalar("Major", state.getClientMajorVersion());
545     json->addScalar("Minor", state.getClientMinorVersion());
546     SerializeColorFWithGroup(json, "ColorClearValue", state.getColorClearValue());
547     json->addScalar("DepthClearValue", state.getDepthClearValue());
548     json->addScalar("StencilClearValue", state.getStencilClearValue());
549     SerializeRasterizerState(json, state.getRasterizerState());
550     json->addScalar("ScissorTestEnabled", state.isScissorTestEnabled());
551     SerializeRectangle(json, "Scissors", state.getScissor());
552     SerializeBlendStateExt(json, state.getBlendStateExt());
553     SerializeColorFWithGroup(json, "BlendColor", state.getBlendColor());
554     json->addScalar("SampleAlphaToCoverageEnabled", state.isSampleAlphaToCoverageEnabled());
555     json->addScalar("SampleCoverageEnabled", state.isSampleCoverageEnabled());
556     json->addScalar("SampleCoverageValue", state.getSampleCoverageValue());
557     json->addScalar("SampleCoverageInvert", state.getSampleCoverageInvert());
558     json->addScalar("SampleMaskEnabled", state.isSampleMaskEnabled());
559     json->addScalar("MaxSampleMaskWords", state.getMaxSampleMaskWords());
560     {
561         const auto &sampleMaskValues = state.getSampleMaskValues();
562         GroupScope maskGroup(json, "SampleMaskValues");
563         for (size_t i = 0; i < sampleMaskValues.size(); i++)
564         {
565             json->addScalar(ToString(i), sampleMaskValues[i]);
566         }
567     }
568     SerializeDepthStencilState(json, state.getDepthStencilState());
569     json->addScalar("StencilRef", state.getStencilRef());
570     json->addScalar("StencilBackRef", state.getStencilBackRef());
571     json->addScalar("LineWidth", state.getLineWidth());
572     json->addScalar("GenerateMipmapHint", state.getGenerateMipmapHint());
573     json->addScalar("FragmentShaderDerivativeHint", state.getFragmentShaderDerivativeHint());
574     json->addScalar("BindGeneratesResourceEnabled", state.isBindGeneratesResourceEnabled());
575     json->addScalar("ClientArraysEnabled", state.areClientArraysEnabled());
576     SerializeRectangle(json, "Viewport", state.getViewport());
577     json->addScalar("Near", state.getNearPlane());
578     json->addScalar("Far", state.getFarPlane());
579     json->addString("ClipOrigin", ToString(state.getClipOrigin()));
580     json->addString("ClipDepthMode", ToString(state.getClipDepthMode()));
581     SerializeResourceID(json, "ReadFramebufferID", state.getReadFramebuffer());
582     SerializeResourceID(json, "DrawFramebufferID", state.getDrawFramebuffer());
583     json->addScalar("RenderbufferID", state.getRenderbufferId().value);
584     SerializeResourceID(json, "CurrentProgramID", state.getProgram());
585     SerializeResourceID(json, "CurrentProgramPipelineID", state.getProgramPipeline());
586     json->addString("ProvokingVertex", ToString(state.getProvokingVertex()));
587     const std::vector<gl::VertexAttribCurrentValueData> &vertexAttribCurrentValues =
588         state.getVertexAttribCurrentValues();
589     for (size_t i = 0; i < vertexAttribCurrentValues.size(); i++)
590     {
591         GroupScope vagroup(json, "VertexAttribCurrentValue", static_cast<int>(i));
592         SerializeVertexAttribCurrentValueData(json, vertexAttribCurrentValues[i]);
593     }
594     ASSERT(state.getVertexArray());
595     json->addScalar("VertexArrayID", state.getVertexArray()->id().value);
596     json->addScalar("CurrentValuesTypeMask", state.getCurrentValuesTypeMask().to_ulong());
597     json->addScalar("ActiveSampler", state.getActiveSampler());
598     {
599         GroupScope boundTexturesGroup(json, "BoundTextures");
600         const gl::TextureBindingMap &boundTexturesMap = state.getBoundTexturesForCapture();
601         for (gl::TextureType textureType : AllEnums<gl::TextureType>())
602         {
603             const gl::TextureBindingVector &textures = boundTexturesMap[textureType];
604             GroupScope texturesGroup(json, ToString(textureType));
605             SerializeBindingPointerVector<gl::Texture>(json, textures);
606         }
607     }
608     json->addScalar("TexturesIncompatibleWithSamplers",
609                     state.getTexturesIncompatibleWithSamplers().to_ulong());
610 
611     {
612         GroupScope texturesCacheGroup(json, "ActiveTexturesCache");
613 
614         const gl::ActiveTexturesCache &texturesCache = state.getActiveTexturesCache();
615         for (GLuint textureIndex = 0; textureIndex < texturesCache.size(); ++textureIndex)
616         {
617             const gl::Texture *tex = texturesCache[textureIndex];
618             std::stringstream strstr;
619             strstr << "Tex " << std::setfill('0') << std::setw(2) << textureIndex;
620             json->addScalar(strstr.str(), tex ? tex->id().value : 0);
621         }
622     }
623 
624     {
625         GroupScope samplersGroupScope(json, "Samplers");
626         SerializeBindingPointerVector<gl::Sampler>(json, state.getSamplers());
627     }
628 
629     {
630         GroupScope imageUnitsGroup(json, "BoundImageUnits");
631 
632         const std::vector<gl::ImageUnit> &imageUnits = state.getImageUnits();
633         for (size_t imageUnitIndex = 0; imageUnitIndex < imageUnits.size(); ++imageUnitIndex)
634         {
635             const gl::ImageUnit &imageUnit = imageUnits[imageUnitIndex];
636             SerializeImageUnit(json, imageUnit, static_cast<int>(imageUnitIndex));
637         }
638     }
639 
640     {
641         const gl::ActiveQueryMap &activeQueries = state.getActiveQueriesForCapture();
642         GroupScope activeQueriesGroup(json, "ActiveQueries");
643         for (gl::QueryType queryType : AllEnums<gl::QueryType>())
644         {
645             const gl::BindingPointer<gl::Query> &query = activeQueries[queryType];
646             std::stringstream strstr;
647             strstr << queryType;
648             json->addScalar(strstr.str(), query.id().value);
649         }
650     }
651 
652     {
653         const gl::BoundBufferMap &boundBuffers = state.getBoundBuffersForCapture();
654         GroupScope boundBuffersGroup(json, "BoundBuffers");
655         for (gl::BufferBinding bufferBinding : AllEnums<gl::BufferBinding>())
656         {
657             const gl::BindingPointer<gl::Buffer> &buffer = boundBuffers[bufferBinding];
658             std::stringstream strstr;
659             strstr << bufferBinding;
660             json->addScalar(strstr.str(), buffer.id().value);
661         }
662     }
663 
664     SerializeOffsetBindingPointerVector<gl::Buffer>(json, "UniformBufferBindings",
665                                                     state.getOffsetBindingPointerUniformBuffers());
666     SerializeOffsetBindingPointerVector<gl::Buffer>(
667         json, "AtomicCounterBufferBindings", state.getOffsetBindingPointerAtomicCounterBuffers());
668     SerializeOffsetBindingPointerVector<gl::Buffer>(
669         json, "ShaderStorageBufferBindings", state.getOffsetBindingPointerShaderStorageBuffers());
670     if (state.getCurrentTransformFeedback())
671     {
672         json->addScalar("CurrentTransformFeedback",
673                         state.getCurrentTransformFeedback()->id().value);
674     }
675     SerializePixelUnpackState(json, state.getUnpackState());
676     SerializePixelPackState(json, state.getPackState());
677     json->addScalar("PrimitiveRestartEnabled", state.isPrimitiveRestartEnabled());
678     json->addScalar("MultisamplingEnabled", state.isMultisamplingEnabled());
679     json->addScalar("SampleAlphaToOneEnabled", state.isSampleAlphaToOneEnabled());
680     json->addScalar("CoverageModulation", state.getCoverageModulation());
681     json->addScalar("FramebufferSRGB", state.getFramebufferSRGB());
682     json->addScalar("RobustResourceInitEnabled", state.isRobustResourceInitEnabled());
683     json->addScalar("ProgramBinaryCacheEnabled", state.isProgramBinaryCacheEnabled());
684     json->addScalar("TextureRectangleEnabled", state.isTextureRectangleEnabled());
685     json->addScalar("MaxShaderCompilerThreads", state.getMaxShaderCompilerThreads());
686     json->addScalar("EnabledClipDistances", state.getEnabledClipDistances().to_ulong());
687     json->addScalar("BlendFuncConstantAlphaDrawBuffers",
688                     state.getBlendFuncConstantAlphaDrawBuffers().to_ulong());
689     json->addScalar("BlendFuncConstantColorDrawBuffers",
690                     state.getBlendFuncConstantColorDrawBuffers().to_ulong());
691     json->addScalar("SimultaneousConstantColorAndAlphaBlendFunc",
692                     state.noSimultaneousConstantColorAndAlphaBlendFunc());
693 }
694 
SerializeBufferState(JsonSerializer * json,const gl::BufferState & bufferState)695 void SerializeBufferState(JsonSerializer *json, const gl::BufferState &bufferState)
696 {
697     json->addString("Label", bufferState.getLabel());
698     json->addString("Usage", ToString(bufferState.getUsage()));
699     json->addScalar("Size", bufferState.getSize());
700     json->addScalar("AccessFlags", bufferState.getAccessFlags());
701     json->addScalar("Access", bufferState.getAccess());
702     json->addScalar("Mapped", bufferState.isMapped());
703     json->addScalar("MapOffset", bufferState.getMapOffset());
704     json->addScalar("MapLength", bufferState.getMapLength());
705 }
706 
SerializeBuffer(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Buffer * buffer)707 Result SerializeBuffer(const gl::Context *context,
708                        JsonSerializer *json,
709                        ScratchBuffer *scratchBuffer,
710                        gl::Buffer *buffer)
711 {
712     GroupScope group(json, "Buffer", buffer->id().value);
713     SerializeBufferState(json, buffer->getState());
714     if (buffer->getSize() > 0)
715     {
716         MemoryBuffer *dataPtr = nullptr;
717         ANGLE_CHECK_GL_ALLOC(
718             const_cast<gl::Context *>(context),
719             scratchBuffer->getInitialized(static_cast<size_t>(buffer->getSize()), &dataPtr, 0));
720         ANGLE_TRY(buffer->getSubData(context, 0, dataPtr->size(), dataPtr->data()));
721         json->addBlob("data", dataPtr->data(), dataPtr->size());
722     }
723     else
724     {
725         json->addCString("data", "null");
726     }
727     return Result::Continue;
728 }
729 
SerializeColorGeneric(JsonSerializer * json,const std::string & name,const ColorGeneric & colorGeneric)730 void SerializeColorGeneric(JsonSerializer *json,
731                            const std::string &name,
732                            const ColorGeneric &colorGeneric)
733 {
734     GroupScope group(json, name);
735     ASSERT(colorGeneric.type == ColorGeneric::Type::Float ||
736            colorGeneric.type == ColorGeneric::Type::Int ||
737            colorGeneric.type == ColorGeneric::Type::UInt);
738     json->addCString("Type", ColorGenericTypeToString(colorGeneric.type));
739     if (colorGeneric.type == ColorGeneric::Type::Float)
740     {
741         SerializeColorF(json, colorGeneric.colorF);
742     }
743     else if (colorGeneric.type == ColorGeneric::Type::Int)
744     {
745         SerializeColorI(json, colorGeneric.colorI);
746     }
747     else
748     {
749         SerializeColorUI(json, colorGeneric.colorUI);
750     }
751 }
752 
SerializeSamplerState(JsonSerializer * json,const gl::SamplerState & samplerState)753 void SerializeSamplerState(JsonSerializer *json, const gl::SamplerState &samplerState)
754 {
755     json->addScalar("MinFilter", samplerState.getMinFilter());
756     json->addScalar("MagFilter", samplerState.getMagFilter());
757     json->addScalar("WrapS", samplerState.getWrapS());
758     json->addScalar("WrapT", samplerState.getWrapT());
759     json->addScalar("WrapR", samplerState.getWrapR());
760     json->addScalar("MaxAnisotropy", samplerState.getMaxAnisotropy());
761     json->addScalar("MinLod", samplerState.getMinLod());
762     json->addScalar("MaxLod", samplerState.getMaxLod());
763     json->addScalar("CompareMode", samplerState.getCompareMode());
764     json->addScalar("CompareFunc", samplerState.getCompareFunc());
765     json->addScalar("SRGBDecode", samplerState.getSRGBDecode());
766     SerializeColorGeneric(json, "BorderColor", samplerState.getBorderColor());
767 }
768 
SerializeSampler(JsonSerializer * json,gl::Sampler * sampler)769 void SerializeSampler(JsonSerializer *json, gl::Sampler *sampler)
770 {
771     GroupScope group(json, "Sampler", sampler->id().value);
772     json->addString("Label", sampler->getLabel());
773     SerializeSamplerState(json, sampler->getSamplerState());
774 }
775 
SerializeSwizzleState(JsonSerializer * json,const gl::SwizzleState & swizzleState)776 void SerializeSwizzleState(JsonSerializer *json, const gl::SwizzleState &swizzleState)
777 {
778     json->addScalar("SwizzleRed", swizzleState.swizzleRed);
779     json->addScalar("SwizzleGreen", swizzleState.swizzleGreen);
780     json->addScalar("SwizzleBlue", swizzleState.swizzleBlue);
781     json->addScalar("SwizzleAlpha", swizzleState.swizzleAlpha);
782 }
783 
SerializeRenderbufferState(JsonSerializer * json,const gl::RenderbufferState & renderbufferState)784 void SerializeRenderbufferState(JsonSerializer *json,
785                                 const gl::RenderbufferState &renderbufferState)
786 {
787     GroupScope wg(json, "State");
788     json->addScalar("Width", renderbufferState.getWidth());
789     json->addScalar("Height", renderbufferState.getHeight());
790     SerializeGLFormat(json, renderbufferState.getFormat());
791     json->addScalar("Samples", renderbufferState.getSamples());
792     json->addCString("InitState", InitStateToString(renderbufferState.getInitState()));
793 }
794 
SerializeRenderbuffer(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Renderbuffer * renderbuffer)795 Result SerializeRenderbuffer(const gl::Context *context,
796                              JsonSerializer *json,
797                              ScratchBuffer *scratchBuffer,
798                              gl::Renderbuffer *renderbuffer)
799 {
800     GroupScope wg(json, "Renderbuffer", renderbuffer->id().value);
801     SerializeRenderbufferState(json, renderbuffer->getState());
802     json->addString("Label", renderbuffer->getLabel());
803 
804     if (renderbuffer->initState(GL_NONE, gl::ImageIndex()) == gl::InitState::Initialized)
805     {
806         if (renderbuffer->getSamples() > 1 && renderbuffer->getFormat().info->depthBits > 0)
807         {
808             // Vulkan can't do resolve blits for multisampled depth attachemnts and
809             // we don't implement an emulation, therefore we can't read back any useful
810             // data here.
811             json->addCString("Pixels", "multisampled depth buffer");
812         }
813         else if (renderbuffer->getWidth() * renderbuffer->getHeight() <= 0)
814         {
815             json->addCString("Pixels", "no pixels");
816         }
817         else
818         {
819             const gl::InternalFormat &format = *renderbuffer->getFormat().info;
820 
821             const gl::Extents size(renderbuffer->getWidth(), renderbuffer->getHeight(), 1);
822             gl::PixelPackState packState;
823             packState.alignment = 1;
824 
825             GLenum readFormat = renderbuffer->getImplementationColorReadFormat(context);
826             GLenum readType   = renderbuffer->getImplementationColorReadType(context);
827 
828             GLuint bytes = 0;
829             bool computeOK =
830                 format.computePackUnpackEndByte(readType, size, packState, false, &bytes);
831             ASSERT(computeOK);
832 
833             MemoryBuffer *pixelsPtr = nullptr;
834             ANGLE_CHECK_GL_ALLOC(const_cast<gl::Context *>(context),
835                                  scratchBuffer->getInitialized(bytes, &pixelsPtr, 0));
836 
837             ANGLE_TRY(renderbuffer->getImplementation()->getRenderbufferImage(
838                 context, packState, nullptr, readFormat, readType, pixelsPtr->data()));
839             json->addBlob("Pixels", pixelsPtr->data(), pixelsPtr->size());
840         }
841     }
842     else
843     {
844         json->addCString("Pixels", "Not initialized");
845     }
846     return Result::Continue;
847 }
848 
SerializeWorkGroupSize(JsonSerializer * json,const sh::WorkGroupSize & workGroupSize)849 void SerializeWorkGroupSize(JsonSerializer *json, const sh::WorkGroupSize &workGroupSize)
850 {
851     GroupScope wg(json, "workGroupSize");
852     json->addScalar("x", workGroupSize[0]);
853     json->addScalar("y", workGroupSize[1]);
854     json->addScalar("z", workGroupSize[2]);
855 }
856 
SerializeUniformIndexToBufferBinding(JsonSerializer * json,const gl::ProgramUniformBlockArray<GLuint> & blockToBuffer)857 void SerializeUniformIndexToBufferBinding(JsonSerializer *json,
858                                           const gl::ProgramUniformBlockArray<GLuint> &blockToBuffer)
859 {
860     GroupScope wg(json, "uniformBlockIndexToBufferBinding");
861     for (size_t blockIndex = 0; blockIndex < blockToBuffer.size(); ++blockIndex)
862     {
863         json->addScalar(ToString(blockIndex), blockToBuffer[blockIndex]);
864     }
865 }
866 
SerializeShaderVariable(JsonSerializer * json,const sh::ShaderVariable & shaderVariable)867 void SerializeShaderVariable(JsonSerializer *json, const sh::ShaderVariable &shaderVariable)
868 {
869     GroupScope wg(json, "ShaderVariable");
870     json->addScalar("Type", shaderVariable.type);
871     json->addScalar("Precision", shaderVariable.precision);
872     json->addString("Name", shaderVariable.name);
873     json->addString("MappedName", shaderVariable.mappedName);
874     json->addVector("ArraySizes", shaderVariable.arraySizes);
875     json->addScalar("StaticUse", shaderVariable.staticUse);
876     json->addScalar("Active", shaderVariable.active);
877     for (const sh::ShaderVariable &field : shaderVariable.fields)
878     {
879         SerializeShaderVariable(json, field);
880     }
881     json->addString("StructOrBlockName", shaderVariable.structOrBlockName);
882     json->addString("MappedStructOrBlockName", shaderVariable.mappedStructOrBlockName);
883     json->addScalar("RowMajorLayout", shaderVariable.isRowMajorLayout);
884     json->addScalar("Location", shaderVariable.location);
885     json->addScalar("Binding", shaderVariable.binding);
886     json->addScalar("ImageUnitFormat", shaderVariable.imageUnitFormat);
887     json->addScalar("Offset", shaderVariable.offset);
888     json->addScalar("Readonly", shaderVariable.readonly);
889     json->addScalar("Writeonly", shaderVariable.writeonly);
890     json->addScalar("Index", shaderVariable.index);
891     json->addScalar("YUV", shaderVariable.yuv);
892     json->addCString("Interpolation", InterpolationTypeToString(shaderVariable.interpolation));
893     json->addScalar("Invariant", shaderVariable.isInvariant);
894     json->addScalar("TexelFetchStaticUse", shaderVariable.texelFetchStaticUse);
895 }
896 
SerializeShaderVariablesVector(JsonSerializer * json,const std::vector<sh::ShaderVariable> & shaderVariables)897 void SerializeShaderVariablesVector(JsonSerializer *json,
898                                     const std::vector<sh::ShaderVariable> &shaderVariables)
899 {
900     for (const sh::ShaderVariable &shaderVariable : shaderVariables)
901     {
902         SerializeShaderVariable(json, shaderVariable);
903     }
904 }
905 
SerializeInterfaceBlocksVector(JsonSerializer * json,const std::vector<sh::InterfaceBlock> & interfaceBlocks)906 void SerializeInterfaceBlocksVector(JsonSerializer *json,
907                                     const std::vector<sh::InterfaceBlock> &interfaceBlocks)
908 {
909     for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
910     {
911         GroupScope group(json, "Interface Block");
912         json->addString("Name", interfaceBlock.name);
913         json->addString("MappedName", interfaceBlock.mappedName);
914         json->addString("InstanceName", interfaceBlock.instanceName);
915         json->addScalar("ArraySize", interfaceBlock.arraySize);
916         json->addCString("Layout", BlockLayoutTypeToString(interfaceBlock.layout));
917         json->addScalar("Binding", interfaceBlock.binding);
918         json->addScalar("StaticUse", interfaceBlock.staticUse);
919         json->addScalar("Active", interfaceBlock.active);
920         json->addCString("BlockType", BlockTypeToString(interfaceBlock.blockType));
921         SerializeShaderVariablesVector(json, interfaceBlock.fields);
922     }
923 }
924 
SerializeCompiledShaderState(JsonSerializer * json,const gl::SharedCompiledShaderState & state)925 void SerializeCompiledShaderState(JsonSerializer *json, const gl::SharedCompiledShaderState &state)
926 {
927     json->addCString("Type", gl::ShaderTypeToString(state->shaderType));
928     json->addScalar("Version", state->shaderVersion);
929     json->addString("TranslatedSource", state->translatedSource);
930     json->addVectorAsHash("CompiledBinary", state->compiledBinary);
931     SerializeWorkGroupSize(json, state->localSize);
932     SerializeShaderVariablesVector(json, state->inputVaryings);
933     SerializeShaderVariablesVector(json, state->outputVaryings);
934     SerializeShaderVariablesVector(json, state->uniforms);
935     SerializeInterfaceBlocksVector(json, state->uniformBlocks);
936     SerializeInterfaceBlocksVector(json, state->shaderStorageBlocks);
937     SerializeShaderVariablesVector(json, state->allAttributes);
938     SerializeShaderVariablesVector(json, state->activeAttributes);
939     SerializeShaderVariablesVector(json, state->activeOutputVariables);
940     json->addScalar("NumViews", state->numViews);
941     json->addScalar("SpecConstUsageBits", state->specConstUsageBits.bits());
942     json->addScalar("MetadataFlags", state->metadataFlags.bits());
943     json->addScalar("AdvancedBlendEquations", state->advancedBlendEquations.bits());
944     json->addString("GeometryShaderInputPrimitiveType",
945                     ToString(state->geometryShaderInputPrimitiveType));
946     json->addString("GeometryShaderOutputPrimitiveType",
947                     ToString(state->geometryShaderOutputPrimitiveType));
948     json->addScalar("GeometryShaderMaxVertices", state->geometryShaderMaxVertices);
949     json->addScalar("GeometryShaderInvocations", state->geometryShaderInvocations);
950     json->addScalar("TessControlShaderVertices", state->tessControlShaderVertices);
951     json->addScalar("TessGenMode", state->tessGenMode);
952     json->addScalar("TessGenSpacing", state->tessGenSpacing);
953     json->addScalar("TessGenVertexOrder", state->tessGenVertexOrder);
954     json->addScalar("TessGenPointMode", state->tessGenPointMode);
955 }
956 
SerializeShaderState(JsonSerializer * json,const gl::ShaderState & shaderState)957 void SerializeShaderState(JsonSerializer *json, const gl::ShaderState &shaderState)
958 {
959     GroupScope group(json, "ShaderState");
960     json->addString("Label", shaderState.getLabel());
961     json->addString("Source", shaderState.getSource());
962     json->addCString("CompileStatus", CompileStatusToString(shaderState.getCompileStatus()));
963 }
964 
SerializeShader(const gl::Context * context,JsonSerializer * json,GLuint id,gl::Shader * shader)965 void SerializeShader(const gl::Context *context,
966                      JsonSerializer *json,
967                      GLuint id,
968                      gl::Shader *shader)
969 {
970     // Ensure deterministic compilation.
971     shader->resolveCompile(context);
972 
973     GroupScope group(json, "Shader", id);
974     SerializeShaderState(json, shader->getState());
975     SerializeCompiledShaderState(json, shader->getCompiledState());
976     json->addScalar("Handle", shader->getHandle().value);
977     // TODO: implement MEC context validation only after all contexts have been initialized
978     // http://anglebug.com/8029
979     // json->addScalar("RefCount", shader->getRefCount());
980     json->addScalar("FlaggedForDeletion", shader->isFlaggedForDeletion());
981     // Do not serialize mType because it is already serialized in SerializeCompiledShaderState.
982     json->addString("InfoLogString", shader->getInfoLogString());
983     // Do not serialize compiler resources string because it can vary between test modes.
984 }
985 
SerializeVariableLocationsVector(JsonSerializer * json,const std::string & group_name,const std::vector<gl::VariableLocation> & variableLocations)986 void SerializeVariableLocationsVector(JsonSerializer *json,
987                                       const std::string &group_name,
988                                       const std::vector<gl::VariableLocation> &variableLocations)
989 {
990     GroupScope group(json, group_name);
991     for (size_t locIndex = 0; locIndex < variableLocations.size(); ++locIndex)
992     {
993         const gl::VariableLocation &variableLocation = variableLocations[locIndex];
994         GroupScope vargroup(json, "Location", static_cast<int>(locIndex));
995         json->addScalar("ArrayIndex", variableLocation.arrayIndex);
996         json->addScalar("Index", variableLocation.index);
997         json->addScalar("Ignored", variableLocation.ignored);
998     }
999 }
1000 
SerializeBlockMemberInfo(JsonSerializer * json,const sh::BlockMemberInfo & blockMemberInfo)1001 void SerializeBlockMemberInfo(JsonSerializer *json, const sh::BlockMemberInfo &blockMemberInfo)
1002 {
1003     GroupScope group(json, "BlockMemberInfo");
1004     json->addScalar("Offset", blockMemberInfo.offset);
1005     json->addScalar("Stride", blockMemberInfo.arrayStride);
1006     json->addScalar("MatrixStride", blockMemberInfo.matrixStride);
1007     json->addScalar("IsRowMajorMatrix", blockMemberInfo.isRowMajorMatrix);
1008     json->addScalar("TopLevelArrayStride", blockMemberInfo.topLevelArrayStride);
1009 }
1010 
SerializeBufferVariablesVector(JsonSerializer * json,const std::vector<gl::BufferVariable> & bufferVariables)1011 void SerializeBufferVariablesVector(JsonSerializer *json,
1012                                     const std::vector<gl::BufferVariable> &bufferVariables)
1013 {
1014     for (const gl::BufferVariable &bufferVariable : bufferVariables)
1015     {
1016         GroupScope group(json, "BufferVariable");
1017         json->addString("Name", bufferVariable.name);
1018         json->addString("MappedName", bufferVariable.mappedName);
1019 
1020         json->addScalar("Type", bufferVariable.pod.type);
1021         json->addScalar("Precision", bufferVariable.pod.precision);
1022         json->addScalar("activeUseBits", bufferVariable.activeShaders().to_ulong());
1023         for (const gl::ShaderType shaderType : gl::AllShaderTypes())
1024         {
1025             json->addScalar(
1026                 gl::ShaderTypeToString(shaderType),
1027                 bufferVariable.isActive(shaderType) ? bufferVariable.getId(shaderType) : 0);
1028         }
1029 
1030         json->addScalar("BufferIndex", bufferVariable.pod.bufferIndex);
1031         SerializeBlockMemberInfo(json, bufferVariable.pod.blockInfo);
1032 
1033         json->addScalar("TopLevelArraySize", bufferVariable.pod.topLevelArraySize);
1034         json->addScalar("basicTypeElementCount", bufferVariable.pod.basicTypeElementCount);
1035         json->addScalar("isArray", bufferVariable.pod.isArray);
1036     }
1037 }
1038 
SerializeProgramAliasedBindings(JsonSerializer * json,const gl::ProgramAliasedBindings & programAliasedBindings)1039 void SerializeProgramAliasedBindings(JsonSerializer *json,
1040                                      const gl::ProgramAliasedBindings &programAliasedBindings)
1041 {
1042     for (const auto &programAliasedBinding : programAliasedBindings)
1043     {
1044         GroupScope group(json, programAliasedBinding.first);
1045         json->addScalar("Location", programAliasedBinding.second.location);
1046         json->addScalar("Aliased", programAliasedBinding.second.aliased);
1047     }
1048 }
1049 
SerializeProgramState(JsonSerializer * json,const gl::ProgramState & programState)1050 void SerializeProgramState(JsonSerializer *json, const gl::ProgramState &programState)
1051 {
1052     json->addString("Label", programState.getLabel());
1053     json->addVectorOfStrings("TransformFeedbackVaryingNames",
1054                              programState.getTransformFeedbackVaryingNames());
1055     json->addScalar("BinaryRetrieveableHint", programState.hasBinaryRetrieveableHint());
1056     json->addScalar("Separable", programState.isSeparable());
1057     SerializeProgramAliasedBindings(json, programState.getUniformLocationBindings());
1058 
1059     const gl::ProgramExecutable &executable = programState.getExecutable();
1060 
1061     SerializeWorkGroupSize(json, executable.getComputeShaderLocalSize());
1062     SerializeUniformIndexToBufferBinding(
1063         json, executable.getUniformBlockIndexToBufferBindingForCapture());
1064     SerializeVariableLocationsVector(json, "UniformLocations", executable.getUniformLocations());
1065     SerializeBufferVariablesVector(json, executable.getBufferVariables());
1066     SerializeRange(json, executable.getAtomicCounterUniformRange());
1067     SerializeVariableLocationsVector(json, "SecondaryOutputLocations",
1068                                      executable.getSecondaryOutputLocations());
1069     json->addScalar("NumViews", executable.getNumViews());
1070     json->addScalar("DrawIDLocation", executable.getDrawIDLocation());
1071     json->addScalar("BaseVertexLocation", executable.getBaseVertexLocation());
1072     json->addScalar("BaseInstanceLocation", executable.getBaseInstanceLocation());
1073 }
1074 
SerializeProgramBindings(JsonSerializer * json,const gl::ProgramBindings & programBindings)1075 void SerializeProgramBindings(JsonSerializer *json, const gl::ProgramBindings &programBindings)
1076 {
1077     for (const auto &programBinding : programBindings)
1078     {
1079         json->addScalar(programBinding.first, programBinding.second);
1080     }
1081 }
1082 
1083 template <typename T>
SerializeUniformData(JsonSerializer * json,const gl::Context * context,const gl::ProgramExecutable & executable,gl::UniformLocation loc,GLenum type,GLint size,void (gl::ProgramExecutable::* getFunc)(const gl::Context *,gl::UniformLocation,T *)const)1084 void SerializeUniformData(JsonSerializer *json,
1085                           const gl::Context *context,
1086                           const gl::ProgramExecutable &executable,
1087                           gl::UniformLocation loc,
1088                           GLenum type,
1089                           GLint size,
1090                           void (gl::ProgramExecutable::*getFunc)(const gl::Context *,
1091                                                                  gl::UniformLocation,
1092                                                                  T *) const)
1093 {
1094     std::vector<T> uniformData(gl::VariableComponentCount(type) * size, 0);
1095     (executable.*getFunc)(context, loc, uniformData.data());
1096     json->addVector("Data", uniformData);
1097 }
1098 
SerializeProgram(JsonSerializer * json,const gl::Context * context,GLuint id,gl::Program * program)1099 void SerializeProgram(JsonSerializer *json,
1100                       const gl::Context *context,
1101                       GLuint id,
1102                       gl::Program *program)
1103 {
1104     // Ensure deterministic link.
1105     program->resolveLink(context);
1106 
1107     GroupScope group(json, "Program", id);
1108 
1109     std::vector<GLint> shaderHandles;
1110     for (gl::ShaderType shaderType : gl::AllShaderTypes())
1111     {
1112         gl::Shader *shader = program->getAttachedShader(shaderType);
1113         shaderHandles.push_back(shader ? shader->getHandle().value : 0);
1114     }
1115     json->addVector("Handle", shaderHandles);
1116 
1117     SerializeProgramState(json, program->getState());
1118     json->addScalar("IsValidated", program->isValidated());
1119     SerializeProgramBindings(json, program->getAttributeBindings());
1120     SerializeProgramAliasedBindings(json, program->getFragmentOutputLocations());
1121     SerializeProgramAliasedBindings(json, program->getFragmentOutputIndexes());
1122     json->addScalar("IsLinked", program->isLinked());
1123     json->addScalar("IsFlaggedForDeletion", program->isFlaggedForDeletion());
1124     // TODO: implement MEC context validation only after all contexts have been initialized
1125     // http://anglebug.com/8029
1126     // json->addScalar("RefCount", program->getRefCount());
1127     json->addScalar("ID", program->id().value);
1128 
1129     const gl::ProgramExecutable &executable = program->getExecutable();
1130 
1131     // Serialize uniforms.
1132     {
1133         GroupScope uniformsGroup(json, "Uniforms");
1134         GLint uniformCount = static_cast<GLint>(executable.getUniforms().size());
1135         for (int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex)
1136         {
1137             GroupScope uniformGroup(json, "Uniform", uniformIndex);
1138 
1139             constexpr GLsizei kMaxUniformNameLen = 1024;
1140             char uniformName[kMaxUniformNameLen] = {};
1141             GLint size                           = 0;
1142             GLenum type                          = GL_NONE;
1143             executable.getActiveUniform(uniformIndex, kMaxUniformNameLen, nullptr, &size, &type,
1144                                         uniformName);
1145 
1146             json->addCString("Name", uniformName);
1147             json->addScalar("Size", size);
1148             json->addCString("Type", gl::GLenumToString(gl::GLESEnum::AttributeType, type));
1149 
1150             const gl::UniformLocation loc = executable.getUniformLocation(uniformName);
1151 
1152             if (loc.value == -1)
1153             {
1154                 continue;
1155             }
1156 
1157             switch (gl::VariableComponentType(type))
1158             {
1159                 case GL_FLOAT:
1160                 {
1161                     SerializeUniformData<GLfloat>(json, context, executable, loc, type, size,
1162                                                   &gl::ProgramExecutable::getUniformfv);
1163                     break;
1164                 }
1165                 case GL_BOOL:
1166                 case GL_INT:
1167                 {
1168                     SerializeUniformData<GLint>(json, context, executable, loc, type, size,
1169                                                 &gl::ProgramExecutable::getUniformiv);
1170                     break;
1171                 }
1172                 case GL_UNSIGNED_INT:
1173                 {
1174                     SerializeUniformData<GLuint>(json, context, executable, loc, type, size,
1175                                                  &gl::ProgramExecutable::getUniformuiv);
1176                     break;
1177                 }
1178                 default:
1179                     UNREACHABLE();
1180                     break;
1181             }
1182         }
1183     }
1184 }
1185 
SerializeImageDesc(JsonSerializer * json,size_t descIndex,const gl::ImageDesc & imageDesc)1186 void SerializeImageDesc(JsonSerializer *json, size_t descIndex, const gl::ImageDesc &imageDesc)
1187 {
1188     // Skip serializing unspecified image levels.
1189     if (imageDesc.size.empty())
1190     {
1191         return;
1192     }
1193 
1194     GroupScope group(json, "ImageDesc", static_cast<int>(descIndex));
1195     SerializeExtents(json, imageDesc.size);
1196     SerializeGLFormat(json, imageDesc.format);
1197     json->addScalar("Samples", imageDesc.samples);
1198     json->addScalar("FixesSampleLocations", imageDesc.fixedSampleLocations);
1199     json->addCString("InitState", InitStateToString(imageDesc.initState));
1200 }
1201 
SerializeTextureState(JsonSerializer * json,const gl::TextureState & textureState)1202 void SerializeTextureState(JsonSerializer *json, const gl::TextureState &textureState)
1203 {
1204     json->addString("Type", ToString(textureState.getType()));
1205     SerializeSwizzleState(json, textureState.getSwizzleState());
1206     {
1207         GroupScope samplerStateGroup(json, "SamplerState");
1208         SerializeSamplerState(json, textureState.getSamplerState());
1209     }
1210     json->addCString("SRGB", SrgbOverrideToString(textureState.getSRGBOverride()));
1211     json->addScalar("BaseLevel", textureState.getBaseLevel());
1212     json->addScalar("MaxLevel", textureState.getMaxLevel());
1213     json->addScalar("DepthStencilTextureMode", textureState.getDepthStencilTextureMode());
1214     json->addScalar("BeenBoundAsImage", textureState.hasBeenBoundAsImage());
1215     json->addScalar("ImmutableFormat", textureState.getImmutableFormat());
1216     json->addScalar("ImmutableLevels", textureState.getImmutableLevels());
1217     json->addScalar("Usage", textureState.getUsage());
1218     SerializeRectangle(json, "Crop", textureState.getCrop());
1219     json->addScalar("GenerateMipmapHint", textureState.getGenerateMipmapHint());
1220     json->addCString("InitState", InitStateToString(textureState.getInitState()));
1221     json->addScalar("BoundBufferID", textureState.getBuffer().id().value);
1222 
1223     {
1224         GroupScope descGroup(json, "ImageDescs");
1225         const std::vector<gl::ImageDesc> &imageDescs = textureState.getImageDescs();
1226         for (size_t descIndex = 0; descIndex < imageDescs.size(); ++descIndex)
1227         {
1228             SerializeImageDesc(json, descIndex, imageDescs[descIndex]);
1229         }
1230     }
1231 }
1232 
SerializeTextureData(JsonSerializer * json,const gl::Context * context,gl::Texture * texture,ScratchBuffer * scratchBuffer)1233 Result SerializeTextureData(JsonSerializer *json,
1234                             const gl::Context *context,
1235                             gl::Texture *texture,
1236                             ScratchBuffer *scratchBuffer)
1237 {
1238     gl::ImageIndexIterator imageIter = gl::ImageIndexIterator::MakeGeneric(
1239         texture->getType(), texture->getBaseLevel(), texture->getMipmapMaxLevel() + 1,
1240         gl::ImageIndex::kEntireLevel, gl::ImageIndex::kEntireLevel);
1241     while (imageIter.hasNext())
1242     {
1243         gl::ImageIndex index = imageIter.next();
1244 
1245         // Skip serializing level data if the level index is out of range
1246         GLuint levelIndex = index.getLevelIndex();
1247         if (levelIndex > texture->getMipmapMaxLevel() || levelIndex < texture->getBaseLevel())
1248             continue;
1249 
1250         const gl::ImageDesc &desc = texture->getTextureState().getImageDesc(index);
1251 
1252         if (desc.size.empty())
1253             continue;
1254 
1255         const gl::InternalFormat &format = *desc.format.info;
1256 
1257         // Check for supported textures
1258         ASSERT(index.getType() == gl::TextureType::_2D || index.getType() == gl::TextureType::_3D ||
1259                index.getType() == gl::TextureType::_2DArray ||
1260                index.getType() == gl::TextureType::CubeMap ||
1261                index.getType() == gl::TextureType::CubeMapArray ||
1262                index.getType() == gl::TextureType::_2DMultisampleArray ||
1263                index.getType() == gl::TextureType::_2DMultisample ||
1264                index.getType() == gl::TextureType::External);
1265 
1266         GLenum glFormat = format.format;
1267         GLenum glType   = format.type;
1268 
1269         const gl::Extents size(desc.size.width, desc.size.height, desc.size.depth);
1270         gl::PixelPackState packState;
1271         packState.alignment = 1;
1272 
1273         GLuint endByte  = 0;
1274         bool unpackSize = format.computePackUnpackEndByte(glType, size, packState, true, &endByte);
1275         ASSERT(unpackSize);
1276         MemoryBuffer *texelsPtr = nullptr;
1277         ANGLE_CHECK_GL_ALLOC(const_cast<gl::Context *>(context),
1278                              scratchBuffer->getInitialized(endByte, &texelsPtr, 0));
1279 
1280         std::stringstream label;
1281 
1282         label << "Texels-Level" << index.getLevelIndex();
1283         if (imageIter.current().hasLayer())
1284         {
1285             label << "-Layer" << imageIter.current().getLayerIndex();
1286         }
1287 
1288         if (texture->getState().getInitState() == gl::InitState::Initialized)
1289         {
1290             if (format.compressed)
1291             {
1292                 // TODO: Read back compressed data. http://anglebug.com/6177
1293                 json->addCString(label.str(), "compressed texel data");
1294             }
1295             else
1296             {
1297                 ANGLE_TRY(texture->getTexImage(context, packState, nullptr, index.getTarget(),
1298                                                index.getLevelIndex(), glFormat, glType,
1299                                                texelsPtr->data()));
1300                 json->addBlob(label.str(), texelsPtr->data(), texelsPtr->size());
1301             }
1302         }
1303         else
1304         {
1305             json->addCString(label.str(), "not initialized");
1306         }
1307     }
1308     return Result::Continue;
1309 }
1310 
SerializeTexture(const gl::Context * context,JsonSerializer * json,ScratchBuffer * scratchBuffer,gl::Texture * texture)1311 Result SerializeTexture(const gl::Context *context,
1312                         JsonSerializer *json,
1313                         ScratchBuffer *scratchBuffer,
1314                         gl::Texture *texture)
1315 {
1316     GroupScope group(json, "Texture", texture->getId());
1317 
1318     // We serialize texture data first, to force the texture state to be initialized.
1319     if (texture->getType() != gl::TextureType::Buffer)
1320     {
1321         ANGLE_TRY(SerializeTextureData(json, context, texture, scratchBuffer));
1322     }
1323 
1324     SerializeTextureState(json, texture->getState());
1325     json->addString("Label", texture->getLabel());
1326     // FrameCapture can not serialize mBoundSurface and mBoundStream
1327     // because they are likely to change with each run
1328     return Result::Continue;
1329 }
1330 
SerializeVertexAttributeVector(JsonSerializer * json,const std::vector<gl::VertexAttribute> & vertexAttributes)1331 void SerializeVertexAttributeVector(JsonSerializer *json,
1332                                     const std::vector<gl::VertexAttribute> &vertexAttributes)
1333 {
1334     for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
1335     {
1336         GroupScope group(json, "VertexAttribute", static_cast<int>(attribIndex));
1337         const gl::VertexAttribute &vertexAttribute = vertexAttributes[attribIndex];
1338         json->addScalar("BindingIndex", vertexAttribute.bindingIndex);
1339         json->addScalar("Enabled", vertexAttribute.enabled);
1340         ASSERT(vertexAttribute.format);
1341         SerializeANGLEFormat(json, vertexAttribute.format);
1342         json->addScalar("RelativeOffset", vertexAttribute.relativeOffset);
1343         json->addScalar("VertexAttribArrayStride", vertexAttribute.vertexAttribArrayStride);
1344     }
1345 }
1346 
SerializeVertexBindingsVector(JsonSerializer * json,const std::vector<gl::VertexBinding> & vertexBindings)1347 void SerializeVertexBindingsVector(JsonSerializer *json,
1348                                    const std::vector<gl::VertexBinding> &vertexBindings)
1349 {
1350     for (size_t bindingIndex = 0; bindingIndex < vertexBindings.size(); ++bindingIndex)
1351     {
1352         GroupScope group(json, "VertexBinding", static_cast<int>(bindingIndex));
1353         const gl::VertexBinding &vertexBinding = vertexBindings[bindingIndex];
1354         json->addScalar("Stride", vertexBinding.getStride());
1355         json->addScalar("Divisor", vertexBinding.getDivisor());
1356         json->addScalar("Offset", vertexBinding.getOffset());
1357         json->addScalar("BufferID", vertexBinding.getBuffer().id().value);
1358         json->addScalar("BoundAttributesMask", vertexBinding.getBoundAttributesMask().to_ulong());
1359     }
1360 }
1361 
SerializeVertexArrayState(JsonSerializer * json,const gl::VertexArrayState & vertexArrayState)1362 void SerializeVertexArrayState(JsonSerializer *json, const gl::VertexArrayState &vertexArrayState)
1363 {
1364     json->addString("Label", vertexArrayState.getLabel());
1365     SerializeVertexAttributeVector(json, vertexArrayState.getVertexAttributes());
1366     if (vertexArrayState.getElementArrayBuffer())
1367     {
1368         json->addScalar("ElementArrayBufferID",
1369                         vertexArrayState.getElementArrayBuffer()->id().value);
1370     }
1371     else
1372     {
1373         json->addScalar("ElementArrayBufferID", 0);
1374     }
1375     SerializeVertexBindingsVector(json, vertexArrayState.getVertexBindings());
1376     json->addScalar("EnabledAttributesMask",
1377                     vertexArrayState.getEnabledAttributesMask().to_ulong());
1378     json->addScalar("VertexAttributesTypeMask",
1379                     vertexArrayState.getVertexAttributesTypeMask().to_ulong());
1380     json->addScalar("ClientMemoryAttribsMask",
1381                     vertexArrayState.getClientMemoryAttribsMask().to_ulong());
1382     json->addScalar("NullPointerClientMemoryAttribsMask",
1383                     vertexArrayState.getNullPointerClientMemoryAttribsMask().to_ulong());
1384 }
1385 
SerializeVertexArray(JsonSerializer * json,gl::VertexArray * vertexArray)1386 void SerializeVertexArray(JsonSerializer *json, gl::VertexArray *vertexArray)
1387 {
1388     GroupScope group(json, "VertexArray", vertexArray->id().value);
1389     SerializeVertexArrayState(json, vertexArray->getState());
1390     json->addScalar("BufferAccessValidationEnabled",
1391                     vertexArray->isBufferAccessValidationEnabled());
1392 }
1393 
1394 }  // namespace
1395 
SerializeContextToString(const gl::Context * context,std::string * stringOut)1396 Result SerializeContextToString(const gl::Context *context, std::string *stringOut)
1397 {
1398     JsonSerializer json;
1399     json.startGroup("Context");
1400 
1401     SerializeContextState(&json, context->getState());
1402     ScratchBuffer scratchBuffer(1);
1403     {
1404         const gl::FramebufferManager &framebufferManager =
1405             context->getState().getFramebufferManagerForCapture();
1406         GroupScope framebufferGroup(&json, "FramebufferManager");
1407         for (const auto &framebuffer :
1408              gl::UnsafeResourceMapIter(framebufferManager.getResourcesForCapture()))
1409         {
1410             gl::Framebuffer *framebufferPtr = framebuffer.second;
1411             ANGLE_TRY(SerializeFramebuffer(context, &json, &scratchBuffer, framebufferPtr));
1412         }
1413     }
1414     {
1415         const gl::BufferManager &bufferManager = context->getState().getBufferManagerForCapture();
1416         GroupScope framebufferGroup(&json, "BufferManager");
1417         for (const auto &buffer : gl::UnsafeResourceMapIter(bufferManager.getResourcesForCapture()))
1418         {
1419             gl::Buffer *bufferPtr = buffer.second;
1420             ANGLE_TRY(SerializeBuffer(context, &json, &scratchBuffer, bufferPtr));
1421         }
1422     }
1423     {
1424         const gl::SamplerManager &samplerManager =
1425             context->getState().getSamplerManagerForCapture();
1426         GroupScope samplerGroup(&json, "SamplerManager");
1427         for (const auto &sampler :
1428              gl::UnsafeResourceMapIter(samplerManager.getResourcesForCapture()))
1429         {
1430             gl::Sampler *samplerPtr = sampler.second;
1431             SerializeSampler(&json, samplerPtr);
1432         }
1433     }
1434     {
1435         const gl::RenderbufferManager &renderbufferManager =
1436             context->getState().getRenderbufferManagerForCapture();
1437         GroupScope renderbufferGroup(&json, "RenderbufferManager");
1438         for (const auto &renderbuffer :
1439              gl::UnsafeResourceMapIter(renderbufferManager.getResourcesForCapture()))
1440         {
1441             gl::Renderbuffer *renderbufferPtr = renderbuffer.second;
1442             ANGLE_TRY(SerializeRenderbuffer(context, &json, &scratchBuffer, renderbufferPtr));
1443         }
1444     }
1445     const gl::ShaderProgramManager &shaderProgramManager =
1446         context->getState().getShaderProgramManagerForCapture();
1447     {
1448         const gl::ResourceMap<gl::Shader, gl::ShaderProgramID> &shaderManager =
1449             shaderProgramManager.getShadersForCapture();
1450         GroupScope shaderGroup(&json, "ShaderManager");
1451         for (const auto &shader : gl::UnsafeResourceMapIter(shaderManager))
1452         {
1453             GLuint id             = shader.first;
1454             gl::Shader *shaderPtr = shader.second;
1455             SerializeShader(context, &json, id, shaderPtr);
1456         }
1457     }
1458     {
1459         const gl::ResourceMap<gl::Program, gl::ShaderProgramID> &programManager =
1460             shaderProgramManager.getProgramsForCaptureAndPerf();
1461         GroupScope shaderGroup(&json, "ProgramManager");
1462         for (const auto &program : gl::UnsafeResourceMapIter(programManager))
1463         {
1464             GLuint id               = program.first;
1465             gl::Program *programPtr = program.second;
1466             SerializeProgram(&json, context, id, programPtr);
1467         }
1468     }
1469     {
1470         const gl::TextureManager &textureManager =
1471             context->getState().getTextureManagerForCapture();
1472         GroupScope shaderGroup(&json, "TextureManager");
1473         for (const auto &texture :
1474              gl::UnsafeResourceMapIter(textureManager.getResourcesForCapture()))
1475         {
1476             gl::Texture *texturePtr = texture.second;
1477             ANGLE_TRY(SerializeTexture(context, &json, &scratchBuffer, texturePtr));
1478         }
1479     }
1480     {
1481         const gl::VertexArrayMap &vertexArrayMap = context->getVertexArraysForCapture();
1482         GroupScope shaderGroup(&json, "VertexArrayMap");
1483         for (const auto &vertexArray : gl::UnsafeResourceMapIter(vertexArrayMap))
1484         {
1485             gl::VertexArray *vertexArrayPtr = vertexArray.second;
1486             SerializeVertexArray(&json, vertexArrayPtr);
1487         }
1488     }
1489     json.endGroup();
1490 
1491     *stringOut = json.data();
1492 
1493     scratchBuffer.clear();
1494     return Result::Continue;
1495 }
1496 
1497 }  // namespace angle
1498