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)
90 for(auto& cmd : commandBuffer->GetCommands())
100 case GLES::CommandType::FLUSH:
102 fprintf(output, "{\"Cmd\":\"FLUSH\"}\n");
105 case GLES::CommandType::BIND_TEXTURES:
107 fprintf(output, "{\"Cmd\":\"BIND_TEXTURES\"}\n");
110 case GLES::CommandType::BIND_VERTEX_BUFFERS:
112 fprintf(output, "{\"Cmd\":\"BIND_VERTEX_BUFFERS\"}\n");
115 case GLES::CommandType::BIND_UNIFORM_BUFFER:
117 fprintf(output, "{\"Cmd\":\"BIND_UNIFORM_BUFFERS\"}\n");
120 case GLES::CommandType::BIND_INDEX_BUFFER:
122 fprintf(output, "{\"Cmd\":\"BIND_INDEX_BUFFERS\"}\n");
125 case GLES::CommandType::BIND_SAMPLERS:
127 fprintf(output, "{\"Cmd\":\"BIND_SAMPLERS\"}\n");
130 case GLES::CommandType::BIND_PIPELINE:
132 fprintf(output, "{\"Cmd\":\"BIND_PIPELINE\"}\n");
135 case GLES::CommandType::DRAW:
137 fprintf(output, "{\"Cmd\":\"DRAW\"}\n");
140 case GLES::CommandType::DRAW_INDEXED:
142 fprintf(output, "{\"Cmd\":\"DRAW_INDEXED\"}\n");
145 case GLES::CommandType::DRAW_INDEXED_INDIRECT:
147 fprintf(output, "{\"Cmd\":\"DRAW_INDEXED_INDIRECT\"}\n");
150 case GLES::CommandType::SET_SCISSOR: // @todo Consider correcting for orientation here?
152 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);
155 case GLES::CommandType::SET_SCISSOR_TEST:
157 fprintf(output, "{\"Cmd\":\"SET_SCISSOR_TEST\",\n\"enable\":%s\n}\n", (cmd.scissorTest.enable ? "\"true\"" : "\"false\""));
160 case GLES::CommandType::SET_VIEWPORT: // @todo Consider correcting for orientation here?
162 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);
165 case GLES::CommandType::SET_COLOR_MASK:
167 fprintf(output, "{\"Cmd\":\"SET_COLOR_MASK\",\n\"enable\":%s\n}\n", (cmd.colorMask.enabled ? "\"true\"" : "\"false\""));
170 case GLES::CommandType::CLEAR_STENCIL_BUFFER:
172 fprintf(output, "{\"Cmd\":\"CLEAR_STENCIL_BUFFER\"}\n");
175 case GLES::CommandType::CLEAR_DEPTH_BUFFER:
177 fprintf(output, "{\"Cmd\":\"CLEAR_DEPTH_BUFFER\"}\n");
181 case GLES::CommandType::SET_STENCIL_TEST_ENABLE:
183 fprintf(output, "{\"Cmd\":\"SET_STENCIL_TEST_ENABLE\",\n\"enable\":%s\n}\n", (cmd.stencilTest.enabled ? "\"true\"" : "\"false\""));
187 case GLES::CommandType::SET_STENCIL_FUNC:
190 "{\"Cmd\":\"STENCIL_FUNC\",\n"
191 "\"compareOp\":\"%s\",\n"
192 "\"reference\":\"0x%x\",\n"
193 "\"compareMask\":\"0x%x\"\n}",
194 DumpCompareOp(cmd.stencilFunc.compareOp).c_str(),
195 cmd.stencilFunc.reference,
196 cmd.stencilFunc.compareMask);
200 case GLES::CommandType::SET_STENCIL_WRITE_MASK:
202 fprintf(output, "{\"Cmd\":\"SET_STENCIL_WRITE_MASK\",\n\"mask\":%d\n}\n", cmd.stencilWriteMask.mask);
206 case GLES::CommandType::SET_STENCIL_OP:
209 "{\"Cmd\":\"SET_STENCIL_OP\",\n"
210 "\"failOp\":\"%s\",\n"
211 "\"depthFailOp\":\"%s\",\n"
212 "\"passOp\":\"%s\"\n}",
214 DumpStencilOp(cmd.stencilOp.failOp).c_str(),
215 DumpStencilOp(cmd.stencilOp.depthFailOp).c_str(),
216 DumpStencilOp(cmd.stencilOp.passOp).c_str());
220 case GLES::CommandType::SET_DEPTH_COMPARE_OP:
223 "{\"Cmd\":\"SET_DEPTH_COMPARE_OP\",\n"
224 "\"compareOp\":\"%s\"\n}\n",
225 DumpCompareOp(cmd.depth.compareOp).c_str());
228 case GLES::CommandType::SET_DEPTH_TEST_ENABLE:
230 fprintf(output, "{\"Cmd\":\"SET_DEPTH_TEST_ENABLE\",\n\"enable\":%s\n}\n", (cmd.depth.testEnabled ? "\"true\"" : "\"false\""));
233 case GLES::CommandType::SET_DEPTH_WRITE_ENABLE:
235 fprintf(output, "{\"Cmd\":\"SET_DEPTH_WRITE_ENABLE\",\n\"enable\":%s\n}\n", (cmd.depth.writeEnabled ? "\"true\"" : "\"false\""));
239 case GLES::CommandType::BEGIN_RENDERPASS:
242 "{\"Cmd\":\"BEGIN_RENDER_PASS\",\n"
243 "\"renderTarget\":\"%p\",\n"
244 "\"renderPass\":\"%p\",\n"
245 "\"renderArea\":[%d,%d,%d,%d],\n",
246 cmd.beginRenderPass.renderTarget,
247 cmd.beginRenderPass.renderPass,
248 cmd.beginRenderPass.renderArea.x,
249 cmd.beginRenderPass.renderArea.y,
250 cmd.beginRenderPass.renderArea.width,
251 cmd.beginRenderPass.renderArea.height);
252 fprintf(output, "\"clearValues\":[");
254 for(auto& value : cmd.beginRenderPass.clearValues)
258 fprintf(output, ",");
261 fprintf(output, "[%f,%f,%f,%f]", value.color.r, value.color.g, value.color.b, value.color.a);
263 fprintf(output, "]\n}");
266 case GLES::CommandType::END_RENDERPASS:
268 fprintf(output, "{\"Cmd\":\"END_RENDER_PASS\"}\n");
271 case GLES::CommandType::PRESENT_RENDER_TARGET:
273 fprintf(output, "{\"Cmd\":\"PRESENT_RENDER_TARGET\"}\n");
276 case GLES::CommandType::EXECUTE_COMMAND_BUFFERS:
278 fprintf(output, "{\"Cmd\":\"EXECUTE_COMMAND_BUFFERS\",\n\"buffers\":[");
280 for(auto& buf : cmd.executeCommandBuffers.buffers)
284 fprintf(output, ", ");
287 DumpCommandBuffer(output, static_cast<const GLES::CommandBuffer*>(buf));
289 fprintf(output, "]\n}");
296 GraphicsFrameDump::GraphicsFrameDump()
297 : outputStream(nullptr, nullptr)
299 char* outfile = getenv("GRAPHICS_CMDBUF_OUTFILE");
302 outputStream = UniqueFilePtr(std::fopen(outfile, "w"), std::fclose);
303 output = outputStream.get();
309 void GraphicsFrameDump::Start()
315 fprintf(output, ", \n");
320 fprintf(output, "{\"Queue #%d\":[\n", frameCount);
324 void GraphicsFrameDump::DumpCommandBuffer(const GLES::CommandBuffer* cmdBuf)
330 fprintf(output, ", \n");
333 fprintf(output, "[\n");
334 Graphics::DumpCommandBuffer(output, cmdBuf);
335 fprintf(output, "]\n");
339 void GraphicsFrameDump::End()
343 fprintf(output, "]}\n");
346 dumpingFrame = false;
349 bool GraphicsFrameDump::IsDumpFrame()
355 dump = (frameCount < NTH_FRAME);
357 // Or, could also use an enviroment variable as a trigger
358 // e.g. if getenv(X) is set, then start dumping again, and clear X.
363 } // namespace Dali::Graphics