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