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"
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 vogl_warning_printf("%s: Waiting for window to resize\n", VOGL_METHOD_NAME);
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 vogl_error_printf("%s: Replay unable to apply snapshot\n", VOGL_FUNCTION_NAME);
133 bool vogleditor_traceReplayer::recursive_replay_apicallTreeItem(vogleditor_apiCallTreeItem* pItem, vogleditor_gl_state_snapshot** ppNewSnapshot, uint64_t apiCallNumber)
137 vogleditor_apiCallItem* pApiCall = pItem->apiCallItem();
138 if (pApiCall != NULL)
140 vogl_trace_packet* pTrace_packet = pApiCall->getTracePacket();
142 vogl_gl_replayer::status_t status = vogl_gl_replayer::cStatusOK;
144 // 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.
145 while (m_pTraceReplayer->get_has_pending_window_resize() || m_pTraceReplayer->get_pending_apply_snapshot())
147 // Pump X events in case the window is resizing
148 bStatus = process_x_events();
151 status = m_pTraceReplayer->process_pending_window_resize();
152 if (status != vogl_gl_replayer::cStatusResizeWindow)
157 // most likely the window wants to close, so let's return
162 // replay the trace packet
163 if (status == vogl_gl_replayer::cStatusOK)
164 status = m_pTraceReplayer->process_next_packet(*pTrace_packet);
166 // if that was successful, check to see if a state snapshot is needed
167 if ((status != vogl_gl_replayer::cStatusHardFailure) && (status != vogl_gl_replayer::cStatusAtEOF))
169 if (ppNewSnapshot != NULL)
171 // get the snapshot after the selected api call
172 if ((!*ppNewSnapshot) && (m_pTraceReplayer->get_last_processed_call_counter() == static_cast<int64_t>(apiCallNumber)))
174 vogl_printf("Taking snapshot on API call # %" PRIu64 "\n", apiCallNumber);
176 *ppNewSnapshot = vogl_new(vogleditor_gl_state_snapshot, m_pTraceReplayer->snapshot_state());
178 if (*ppNewSnapshot == NULL)
180 vogl_error_printf("Snapshot failed!\n");
184 vogl_printf("Snapshot succeeded\n");
193 // replaying the trace packet failed, set as error
194 vogl_error_printf("%s: unable to replay gl entrypoint at call %" PRIu64 "\n", VOGL_FUNCTION_NAME, pTrace_packet->get_call_counter());
199 if (bStatus && pItem->has_snapshot() && pItem->get_snapshot()->is_edited() && pItem->get_snapshot()->is_valid())
201 bStatus = applying_snapshot_and_process_resize(pItem->get_snapshot()->get_snapshot());
206 for (int i = 0; i < pItem->childCount(); i++)
208 bStatus = recursive_replay_apicallTreeItem(pItem->child(i), ppNewSnapshot, apiCallNumber);
218 bool vogleditor_traceReplayer::replay(vogl_trace_file_reader* m_pTraceReader, vogleditor_apiCallTreeItem* pRootItem, vogleditor_gl_state_snapshot** ppNewSnapshot, uint64_t apiCallNumber, bool endlessMode)
220 // reset to beginnning of trace file.
221 m_pTraceReader->seek_to_frame(0);
223 int initial_window_width = 1280;
224 int initial_window_height = 1024;
226 if (!m_window.open(initial_window_width, initial_window_height))
228 vogl_error_printf("%s: Failed opening GL replayer window!\n", VOGL_FUNCTION_NAME);
232 uint replayer_flags = cGLReplayerForceDebugContexts;
233 if (!m_pTraceReplayer->init(replayer_flags, &m_window, m_pTraceReader->get_sof_packet(), m_pTraceReader->get_multi_blob_manager()))
235 vogl_error_printf("%s: Failed initializing GL replayer\n", VOGL_FUNCTION_NAME);
240 XSelectInput(m_window.get_display(), m_window.get_xwindow(),
241 EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
243 m_wmDeleteMessage = XInternAtom(m_window.get_display(), "WM_DELETE_WINDOW", False);
244 XSetWMProtocols(m_window.get_display(), m_window.get_xwindow(), &m_wmDeleteMessage, 1);
253 if (process_x_events() == false)
258 if (pRootItem->childCount() > 0)
260 vogleditor_apiCallTreeItem* pFirstFrame = pRootItem->child(0);
262 // if the first snapshot has not been edited, then restore it here, otherwise it will get restored in the recursive call below.
263 if (pFirstFrame->has_snapshot() && !pFirstFrame->get_snapshot()->is_edited())
265 bStatus = applying_snapshot_and_process_resize(pFirstFrame->get_snapshot()->get_snapshot());
270 // replay each API call.
271 bStatus = recursive_replay_apicallTreeItem(pRootItem, ppNewSnapshot, apiCallNumber);
273 if (bStatus == false)
275 vogl_error_printf("%s: Replay ending abruptly at frame index %u, global api call %" PRIu64 "\n", VOGL_FUNCTION_NAME, m_pTraceReplayer->get_frame_index(), m_pTraceReplayer->get_last_processed_call_counter());
280 vogl_message_printf("%s: At trace EOF, frame index %u\n", VOGL_FUNCTION_NAME, m_pTraceReplayer->get_frame_index());
294 m_pTraceReplayer->deinit();
299 bool vogleditor_traceReplayer::pause()
301 VOGL_ASSERT(!"Not implemented");
305 bool vogleditor_traceReplayer::restart()
307 VOGL_ASSERT(!"Not implemented");
311 bool vogleditor_traceReplayer::trim()
313 VOGL_ASSERT(!"Not implemented");
317 bool vogleditor_traceReplayer::stop()
319 VOGL_ASSERT(!"Not implemented");