2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <dali/internal/graphics/gles-impl/egl-graphics-controller-debug.h>
21 namespace Dali::Graphics
23 std::string DumpCompareOp(Graphics::CompareOp compareOp)
27 case Graphics::CompareOp::NEVER:
28 return "Graphics::CompareOp::NEVER";
30 case Graphics::CompareOp::LESS:
31 return "Graphics::CompareOp::LESS";
33 case Graphics::CompareOp::EQUAL:
34 return "Graphics::CompareOp::EQUAL";
36 case Graphics::CompareOp::LESS_OR_EQUAL:
37 return "Graphics::CompareOp::LESS_OR_EQUAL";
39 case Graphics::CompareOp::GREATER:
40 return "Graphics::CompareOp::GREATER";
42 case Graphics::CompareOp::NOT_EQUAL:
43 return "Graphics::CompareOp::NOT_EQUAL";
45 case Graphics::CompareOp::GREATER_OR_EQUAL:
46 return "Graphics::CompareOp::GREATER_OR_EQUAL";
48 case Graphics::CompareOp::ALWAYS:
49 return "Graphics::CompareOp::ALWAYS";
55 std::string DumpStencilOp(Graphics::StencilOp stencilOp)
59 case Graphics::StencilOp::KEEP:
60 return "Graphics::StencilOp::KEEP";
62 case Graphics::StencilOp::ZERO:
63 return "Graphics::StencilOp::ZERO";
65 case Graphics::StencilOp::REPLACE:
66 return "Graphics::StencilOp::REPLACE";
68 case Graphics::StencilOp::INCREMENT_AND_CLAMP:
69 return "Graphics::StencilOp::INCREMENT_AND_CLAMP";
71 case Graphics::StencilOp::DECREMENT_AND_CLAMP:
72 return "Graphics::StencilOp::DECREMENT_AND_CLAMP";
74 case Graphics::StencilOp::INVERT:
75 return "Graphics::StencilOp::INVERT";
77 case Graphics::StencilOp::INCREMENT_AND_WRAP:
78 return "Graphics::StencilOp::INCREMENT_AND_WRAP";
80 case Graphics::StencilOp::DECREMENT_AND_WRAP:
81 return "Graphics::StencilOp::DECREMENT_AND_WRAP";
87 void DumpCommandBuffer(FILE* output, const GLES::CommandBuffer* commandBuffer)
91 const auto command = commandBuffer->GetCommands(count);
92 for(auto i = 0u; i < count; ++i)
94 auto& cmd = command[i];
103 case GLES::CommandType::FLUSH:
105 fprintf(output, "{\"Cmd\":\"FLUSH\"}\n");
108 case GLES::CommandType::BIND_TEXTURES:
110 fprintf(output, "{\"Cmd\":\"BIND_TEXTURES\"}\n");
113 case GLES::CommandType::BIND_VERTEX_BUFFERS:
115 fprintf(output, "{\"Cmd\":\"BIND_VERTEX_BUFFERS\"}\n");
118 case GLES::CommandType::BIND_UNIFORM_BUFFER:
120 fprintf(output, "{\"Cmd\":\"BIND_UNIFORM_BUFFERS\"}\n");
123 case GLES::CommandType::BIND_INDEX_BUFFER:
125 fprintf(output, "{\"Cmd\":\"BIND_INDEX_BUFFERS\"}\n");
128 case GLES::CommandType::BIND_SAMPLERS:
130 fprintf(output, "{\"Cmd\":\"BIND_SAMPLERS\"}\n");
133 case GLES::CommandType::BIND_PIPELINE:
135 fprintf(output, "{\"Cmd\":\"BIND_PIPELINE\"}\n");
138 case GLES::CommandType::DRAW:
140 fprintf(output, "{\"Cmd\":\"DRAW\"}\n");
143 case GLES::CommandType::DRAW_INDEXED:
145 fprintf(output, "{\"Cmd\":\"DRAW_INDEXED\"}\n");
148 case GLES::CommandType::DRAW_INDEXED_INDIRECT:
150 fprintf(output, "{\"Cmd\":\"DRAW_INDEXED_INDIRECT\"}\n");
153 case GLES::CommandType::SET_SCISSOR: // @todo Consider correcting for orientation here?
155 fprintf(output, "{\"Cmd\":\"SET_SCISSOR\",\n\"region\":[%d,%d,%d,%d]\n}\n", cmd.scissor.region.x, cmd.scissor.region.y, cmd.scissor.region.width, cmd.scissor.region.height);
158 case GLES::CommandType::SET_SCISSOR_TEST:
160 fprintf(output, "{\"Cmd\":\"SET_SCISSOR_TEST\",\n\"enable\":%s\n}\n", (cmd.scissorTest.enable ? "\"true\"" : "\"false\""));
163 case GLES::CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here?
165 fprintf(output, "{\"Cmd\":\"SET_VIEWPORT\",\n\"region\":[%f,%f,%f,%f]\n}\n", cmd.viewport.region.x, cmd.viewport.region.y, cmd.viewport.region.width, cmd.viewport.region.height);
168 case GLES::CommandType::SET_COLOR_MASK:
170 fprintf(output, "{\"Cmd\":\"SET_COLOR_MASK\",\n\"enable\":%s\n}\n", (cmd.colorMask.enabled ? "\"true\"" : "\"false\""));
173 case GLES::CommandType::CLEAR_STENCIL_BUFFER:
175 fprintf(output, "{\"Cmd\":\"CLEAR_STENCIL_BUFFER\"}\n");
178 case GLES::CommandType::CLEAR_DEPTH_BUFFER:
180 fprintf(output, "{\"Cmd\":\"CLEAR_DEPTH_BUFFER\"}\n");
184 case GLES::CommandType::SET_STENCIL_TEST_ENABLE:
186 fprintf(output, "{\"Cmd\":\"SET_STENCIL_TEST_ENABLE\",\n\"enable\":%s\n}\n", (cmd.stencilTest.enabled ? "\"true\"" : "\"false\""));
190 case GLES::CommandType::SET_STENCIL_FUNC:
193 "{\"Cmd\":\"STENCIL_FUNC\",\n"
194 "\"compareOp\":\"%s\",\n"
195 "\"reference\":\"0x%x\",\n"
196 "\"compareMask\":\"0x%x\"\n}",
197 DumpCompareOp(cmd.stencilFunc.compareOp).c_str(),
198 cmd.stencilFunc.reference,
199 cmd.stencilFunc.compareMask);
203 case GLES::CommandType::SET_STENCIL_WRITE_MASK:
205 fprintf(output, "{\"Cmd\":\"SET_STENCIL_WRITE_MASK\",\n\"mask\":%d\n}\n", cmd.stencilWriteMask.mask);
209 case GLES::CommandType::SET_STENCIL_OP:
212 "{\"Cmd\":\"SET_STENCIL_OP\",\n"
213 "\"failOp\":\"%s\",\n"
214 "\"depthFailOp\":\"%s\",\n"
215 "\"passOp\":\"%s\"\n}",
217 DumpStencilOp(cmd.stencilOp.failOp).c_str(),
218 DumpStencilOp(cmd.stencilOp.depthFailOp).c_str(),
219 DumpStencilOp(cmd.stencilOp.passOp).c_str());
223 case GLES::CommandType::SET_DEPTH_COMPARE_OP:
226 "{\"Cmd\":\"SET_DEPTH_COMPARE_OP\",\n"
227 "\"compareOp\":\"%s\"\n}\n",
228 DumpCompareOp(cmd.depth.compareOp).c_str());
231 case GLES::CommandType::SET_DEPTH_TEST_ENABLE:
233 fprintf(output, "{\"Cmd\":\"SET_DEPTH_TEST_ENABLE\",\n\"enable\":%s\n}\n", (cmd.depth.testEnabled ? "\"true\"" : "\"false\""));
236 case GLES::CommandType::SET_DEPTH_WRITE_ENABLE:
238 fprintf(output, "{\"Cmd\":\"SET_DEPTH_WRITE_ENABLE\",\n\"enable\":%s\n}\n", (cmd.depth.writeEnabled ? "\"true\"" : "\"false\""));
242 case GLES::CommandType::BEGIN_RENDERPASS:
245 "{\"Cmd\":\"BEGIN_RENDER_PASS\",\n"
246 "\"renderTarget\":\"%p\",\n"
247 "\"renderPass\":\"%p\",\n"
248 "\"renderArea\":[%d,%d,%d,%d],\n",
249 cmd.beginRenderPass.renderTarget,
250 cmd.beginRenderPass.renderPass,
251 cmd.beginRenderPass.renderArea.x,
252 cmd.beginRenderPass.renderArea.y,
253 cmd.beginRenderPass.renderArea.width,
254 cmd.beginRenderPass.renderArea.height);
255 fprintf(output, "\"clearValues\":[");
257 for(auto i = 0u; i < cmd.beginRenderPass.clearValuesCount; ++i)
259 auto value = cmd.beginRenderPass.clearValues.Ptr()[i];
262 fprintf(output, ",");
265 fprintf(output, "[%f,%f,%f,%f]", value.color.r, value.color.g, value.color.b, value.color.a);
267 fprintf(output, "]\n}");
270 case GLES::CommandType::END_RENDERPASS:
272 fprintf(output, "{\"Cmd\":\"END_RENDER_PASS\"}\n");
275 case GLES::CommandType::PRESENT_RENDER_TARGET:
277 fprintf(output, "{\"Cmd\":\"PRESENT_RENDER_TARGET\"}\n");
280 case GLES::CommandType::EXECUTE_COMMAND_BUFFERS:
282 fprintf(output, "{\"Cmd\":\"EXECUTE_COMMAND_BUFFERS\",\n\"buffers\":[");
284 for(auto i = 0u; i < cmd.executeCommandBuffers.buffersCount; ++i)
286 const auto buf = cmd.executeCommandBuffers.buffers.Ptr()[i];
289 fprintf(output, ", ");
292 DumpCommandBuffer(output, buf);
294 fprintf(output, "]\n}");
301 GraphicsFrameDump::GraphicsFrameDump()
302 : outputStream(nullptr, nullptr)
304 char* outfile = getenv("GRAPHICS_CMDBUF_OUTFILE");
307 outputStream = UniqueFilePtr(std::fopen(outfile, "w"), std::fclose);
308 output = outputStream.get();
314 void GraphicsFrameDump::Start()
320 fprintf(output, ", \n");
325 fprintf(output, "{\"Queue #%d\":[\n", frameCount);
329 void GraphicsFrameDump::DumpCommandBuffer(const GLES::CommandBuffer* cmdBuf)
335 fprintf(output, ", \n");
338 fprintf(output, "[\n");
339 Graphics::DumpCommandBuffer(output, cmdBuf);
340 fprintf(output, "]\n");
344 void GraphicsFrameDump::End()
348 fprintf(output, "]}\n");
351 dumpingFrame = false;
354 bool GraphicsFrameDump::IsDumpFrame()
360 dump = (frameCount < NTH_FRAME);
362 // Or, could also use an enviroment variable as a trigger
363 // e.g. if getenv(X) is set, then start dumping again, and clear X.
368 } // namespace Dali::Graphics