2 #include "vogleditor_apicalltreeitem.h"
4 #include "vogleditor_tracereplayer.h"
6 #include "vogl_find_files.h"
7 #include "vogl_file_utils.h"
8 #include "vogl_gl_replayer.h"
9 #include "vogleditor_output.h"
11 vogleditor_traceReplayer::vogleditor_traceReplayer()
12 : m_pTraceReplayer(vogl_new(vogl_gl_replayer))
17 vogleditor_traceReplayer::~vogleditor_traceReplayer()
19 if (m_pTraceReplayer != NULL)
21 vogl_delete(m_pTraceReplayer);
22 m_pTraceReplayer = NULL;
26 //----------------------------------------------------------------------------------------------------------------------
27 // X11_Pending - from SDL
28 //----------------------------------------------------------------------------------------------------------------------
29 static int X11_Pending(Display *display)
33 /* Flush the display connection and look to see if events are queued */
35 if (XEventsQueued(display, QueuedAlready))
40 /* More drastic measures are required -- see if X is ready to talk */
42 static struct timeval zero_time; /* static == 0 */
46 x11_fd = ConnectionNumber(display);
48 FD_SET(x11_fd, &fdset);
49 if (select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1)
51 return(XPending(display));
55 /* Oh well, nothing is ready .. */
59 bool vogleditor_traceReplayer::process_x_events()
61 while (X11_Pending(m_window.get_display()))
65 // Watch for new X events
66 XNextEvent(m_window.get_display(), &newEvent);
68 switch (newEvent.type)
72 m_pTraceReplayer->update_window_dimensions();
77 m_pTraceReplayer->update_window_dimensions();
82 vogl_message_printf("Exiting\n");
88 if(newEvent.xclient.data.l[0] == (int)m_wmDeleteMessage)
90 vogl_message_printf("Exiting\n");
103 bool vogleditor_traceReplayer::applying_snapshot_and_process_resize(const vogl_gl_state_snapshot* pSnapshot)
105 vogl_gl_replayer::status_t status = m_pTraceReplayer->begin_applying_snapshot(pSnapshot, false);
108 while (status == vogl_gl_replayer::cStatusResizeWindow)
110 vogleditor_output_message("Waiting for replay window to resize.");
112 // Pump X events in case the window is resizing
113 if (process_x_events())
115 status = m_pTraceReplayer->process_pending_window_resize();
124 if (bStatus && status != vogl_gl_replayer::cStatusOK)
126 vogleditor_output_error("Replay unable to apply snapshot");
133 vogleditor_tracereplayer_result vogleditor_traceReplayer::recursive_replay_apicallTreeItem(vogleditor_apiCallTreeItem* pItem, vogleditor_gl_state_snapshot** ppNewSnapshot, uint64_t apiCallNumber)
135 vogleditor_tracereplayer_result result = VOGLEDITOR_TRR_SUCCESS;
136 vogleditor_apiCallItem* pApiCall = pItem->apiCallItem();
137 if (pApiCall != NULL)
139 vogl_trace_packet* pTrace_packet = pApiCall->getTracePacket();
141 vogl_gl_replayer::status_t status = vogl_gl_replayer::cStatusOK;
143 // See if a window resize or snapshot is pending. If a window resize is pending we must delay a while and pump X events until the window is resized.
144 while (m_pTraceReplayer->get_has_pending_window_resize() || m_pTraceReplayer->get_pending_apply_snapshot())
146 // Pump X events in case the window is resizing
147 if (process_x_events())
149 status = m_pTraceReplayer->process_pending_window_resize();
150 if (status != vogl_gl_replayer::cStatusResizeWindow)
155 // most likely the window wants to close, so let's return
156 return VOGLEDITOR_TRR_USER_EXIT;
160 // replay the trace packet
161 if (status == vogl_gl_replayer::cStatusOK)
162 status = m_pTraceReplayer->process_next_packet(*pTrace_packet);
164 // if that was successful, check to see if a state snapshot is needed
165 if ((status != vogl_gl_replayer::cStatusHardFailure) && (status != vogl_gl_replayer::cStatusAtEOF))
167 if (ppNewSnapshot != NULL)
169 // get the snapshot after the selected api call
170 if ((!*ppNewSnapshot) && (m_pTraceReplayer->get_last_processed_call_counter() == static_cast<int64_t>(apiCallNumber)))
173 vogleditor_output_message(info.format("Taking snapshot on API call # %" PRIu64 "...", apiCallNumber).c_str());
175 vogl_gl_state_snapshot* pNewSnapshot = m_pTraceReplayer->snapshot_state();
176 if (pNewSnapshot == NULL)
178 result = VOGLEDITOR_TRR_ERROR;
179 vogleditor_output_error("... snapshot failed!");
183 result = VOGLEDITOR_TRR_SNAPSHOT_SUCCESS;
184 vogleditor_output_message("... snapshot succeeded!\n");
185 *ppNewSnapshot = vogl_new(vogleditor_gl_state_snapshot, pNewSnapshot);
186 if (*ppNewSnapshot == NULL)
188 result = VOGLEDITOR_TRR_ERROR;
189 vogleditor_output_error("Allocating memory for snapshot container failed!");
190 vogl_delete(pNewSnapshot);
198 // replaying the trace packet failed, set as error
199 result = VOGLEDITOR_TRR_ERROR;
201 vogleditor_output_error(info.format("Unable to replay gl entrypoint at call %" PRIu64, pTrace_packet->get_call_counter()).c_str());
205 if (result == VOGLEDITOR_TRR_SUCCESS && pItem->has_snapshot() && pItem->get_snapshot()->is_edited() && pItem->get_snapshot()->is_valid())
207 if(applying_snapshot_and_process_resize(pItem->get_snapshot()->get_snapshot()))
209 result = VOGLEDITOR_TRR_SUCCESS;
213 if (result == VOGLEDITOR_TRR_SUCCESS)
215 for (int i = 0; i < pItem->childCount(); i++)
217 result = recursive_replay_apicallTreeItem(pItem->child(i), ppNewSnapshot, apiCallNumber);
219 if (result != VOGLEDITOR_TRR_SUCCESS)
222 // Pump X events in case the window is resizing
223 if (process_x_events() == false)
225 // most likely the window wants to close, so let's return
226 return VOGLEDITOR_TRR_USER_EXIT;
234 vogleditor_tracereplayer_result vogleditor_traceReplayer::replay(vogl_trace_file_reader* m_pTraceReader, vogleditor_apiCallTreeItem* pRootItem, vogleditor_gl_state_snapshot** ppNewSnapshot, uint64_t apiCallNumber, bool endlessMode)
236 // reset to beginnning of trace file.
237 m_pTraceReader->seek_to_frame(0);
239 int initial_window_width = 1280;
240 int initial_window_height = 1024;
242 if (!m_window.open(initial_window_width, initial_window_height))
244 vogleditor_output_error("Failed opening GL replayer window!");
245 return VOGLEDITOR_TRR_ERROR;
248 uint replayer_flags = cGLReplayerForceDebugContexts;
249 if (!m_pTraceReplayer->init(replayer_flags, &m_window, m_pTraceReader->get_sof_packet(), m_pTraceReader->get_multi_blob_manager()))
251 vogleditor_output_error("Failed initializing GL replayer!");
253 return VOGLEDITOR_TRR_ERROR;
256 XSelectInput(m_window.get_display(), m_window.get_xwindow(),
257 EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
259 m_wmDeleteMessage = XInternAtom(m_window.get_display(), "WM_DELETE_WINDOW", False);
260 XSetWMProtocols(m_window.get_display(), m_window.get_xwindow(), &m_wmDeleteMessage, 1);
265 vogleditor_tracereplayer_result result = VOGLEDITOR_TRR_SUCCESS;
269 if (process_x_events() == false)
271 result = VOGLEDITOR_TRR_USER_EXIT;
275 if (pRootItem->childCount() > 0)
277 vogleditor_apiCallTreeItem* pFirstFrame = pRootItem->child(0);
280 // if the first snapshot has not been edited, then restore it here, otherwise it will get restored in the recursive call below.
281 if (pFirstFrame->has_snapshot() && !pFirstFrame->get_snapshot()->is_edited())
283 bStatus = applying_snapshot_and_process_resize(pFirstFrame->get_snapshot()->get_snapshot());
288 // replay each API call.
289 result = recursive_replay_apicallTreeItem(pRootItem, ppNewSnapshot, apiCallNumber);
291 if (result == VOGLEDITOR_TRR_ERROR)
293 QString msg = QString("Replay ending abruptly at frame index %1, global api call %2").arg(m_pTraceReplayer->get_frame_index()).arg(m_pTraceReplayer->get_last_processed_call_counter());
294 vogleditor_output_error(msg.toStdString().c_str());
297 else if (result == VOGLEDITOR_TRR_SNAPSHOT_SUCCESS)
301 else if (result == VOGLEDITOR_TRR_USER_EXIT)
303 vogleditor_output_message("Replay stopped");
308 QString msg = QString("At trace EOF, frame index %1").arg(m_pTraceReplayer->get_frame_index());
309 vogleditor_output_message(msg.toStdString().c_str());
323 m_pTraceReplayer->deinit();
328 bool vogleditor_traceReplayer::pause()
330 VOGL_ASSERT(!"Not implemented");
334 bool vogleditor_traceReplayer::restart()
336 VOGL_ASSERT(!"Not implemented");
340 bool vogleditor_traceReplayer::trim()
342 VOGL_ASSERT(!"Not implemented");
346 bool vogleditor_traceReplayer::stop()
348 VOGL_ASSERT(!"Not implemented");