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 vogl_gl_state_snapshot* pNewSnapshot = m_pTraceReplayer->snapshot_state();
177 if (pNewSnapshot == NULL)
179 vogl_error_printf("Taking new snapshot failed!\n");
183 vogl_printf("Taking snapshot succeeded\n");
184 *ppNewSnapshot = vogl_new(vogleditor_gl_state_snapshot, pNewSnapshot);
185 if (*ppNewSnapshot == NULL)
187 vogl_error_printf("Allocating memory for snapshot container failed!\n");
188 vogl_delete(pNewSnapshot);
198 // replaying the trace packet failed, set as error
199 vogl_error_printf("%s: unable to replay gl entrypoint at call %" PRIu64 "\n", VOGL_FUNCTION_NAME, pTrace_packet->get_call_counter());
204 if (bStatus && pItem->has_snapshot() && pItem->get_snapshot()->is_edited() && pItem->get_snapshot()->is_valid())
206 bStatus = applying_snapshot_and_process_resize(pItem->get_snapshot()->get_snapshot());
211 for (int i = 0; i < pItem->childCount(); i++)
213 bStatus = recursive_replay_apicallTreeItem(pItem->child(i), ppNewSnapshot, apiCallNumber);
223 bool vogleditor_traceReplayer::replay(vogl_trace_file_reader* m_pTraceReader, vogleditor_apiCallTreeItem* pRootItem, vogleditor_gl_state_snapshot** ppNewSnapshot, uint64_t apiCallNumber, bool endlessMode)
225 // reset to beginnning of trace file.
226 m_pTraceReader->seek_to_frame(0);
228 int initial_window_width = 1280;
229 int initial_window_height = 1024;
231 if (!m_window.open(initial_window_width, initial_window_height))
233 vogl_error_printf("%s: Failed opening GL replayer window!\n", VOGL_FUNCTION_NAME);
237 uint replayer_flags = cGLReplayerForceDebugContexts;
238 if (!m_pTraceReplayer->init(replayer_flags, &m_window, m_pTraceReader->get_sof_packet(), m_pTraceReader->get_multi_blob_manager()))
240 vogl_error_printf("%s: Failed initializing GL replayer\n", VOGL_FUNCTION_NAME);
245 XSelectInput(m_window.get_display(), m_window.get_xwindow(),
246 EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
248 m_wmDeleteMessage = XInternAtom(m_window.get_display(), "WM_DELETE_WINDOW", False);
249 XSetWMProtocols(m_window.get_display(), m_window.get_xwindow(), &m_wmDeleteMessage, 1);
258 if (process_x_events() == false)
263 if (pRootItem->childCount() > 0)
265 vogleditor_apiCallTreeItem* pFirstFrame = pRootItem->child(0);
267 // if the first snapshot has not been edited, then restore it here, otherwise it will get restored in the recursive call below.
268 if (pFirstFrame->has_snapshot() && !pFirstFrame->get_snapshot()->is_edited())
270 bStatus = applying_snapshot_and_process_resize(pFirstFrame->get_snapshot()->get_snapshot());
275 // replay each API call.
276 bStatus = recursive_replay_apicallTreeItem(pRootItem, ppNewSnapshot, apiCallNumber);
278 if (bStatus == false)
280 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());
285 vogl_message_printf("%s: At trace EOF, frame index %u\n", VOGL_FUNCTION_NAME, m_pTraceReplayer->get_frame_index());
299 m_pTraceReplayer->deinit();
304 bool vogleditor_traceReplayer::pause()
306 VOGL_ASSERT(!"Not implemented");
310 bool vogleditor_traceReplayer::restart()
312 VOGL_ASSERT(!"Not implemented");
316 bool vogleditor_traceReplayer::trim()
318 VOGL_ASSERT(!"Not implemented");
322 bool vogleditor_traceReplayer::stop()
324 VOGL_ASSERT(!"Not implemented");