1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 #include "util/u_string.h"
30 #include "util/u_memory.h"
31 #include "util/u_simple_list.h"
32 #include "util/u_network.h"
34 #include "tgsi/tgsi_parse.h"
38 #include "tr_buffer.h"
39 #include "tr_texture.h"
41 #include "rbug/rbug.h"
45 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
47 #elif defined(PIPE_OS_LINUX)
51 # warning "No socket implementation"
54 #define U642VOID(x) ((void *)(unsigned long)(x))
55 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
59 struct trace_screen
*tr_scr
;
60 struct rbug_connection
*con
;
65 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
);
68 /**********************************************************
73 static struct trace_context
*
74 trace_rbug_get_context_locked(struct trace_screen
*tr_scr
, rbug_context_t ctx
)
76 struct trace_context
*tr_ctx
= NULL
;
79 foreach(ptr
, &tr_scr
->contexts
) {
80 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
81 if (ctx
== VOID2U64(tr_ctx
))
89 static struct trace_shader
*
90 trace_rbug_get_shader_locked(struct trace_context
*tr_ctx
, rbug_shader_t shdr
)
92 struct trace_shader
*tr_shdr
= NULL
;
95 foreach(ptr
, &tr_ctx
->shaders
) {
96 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
97 if (shdr
== VOID2U64(tr_shdr
))
106 trace_shader_create_locked(struct pipe_context
*pipe
,
107 struct trace_shader
*tr_shdr
,
108 struct tgsi_token
*tokens
)
111 struct pipe_shader_state pss
= { 0 };
114 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
115 state
= pipe
->create_fs_state(pipe
, &pss
);
116 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
117 state
= pipe
->create_vs_state(pipe
, &pss
);
125 trace_shader_bind_locked(struct pipe_context
*pipe
,
126 struct trace_shader
*tr_shdr
,
129 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
130 pipe
->bind_fs_state(pipe
, state
);
131 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
132 pipe
->bind_vs_state(pipe
, state
);
138 trace_shader_delete_locked(struct pipe_context
*pipe
,
139 struct trace_shader
*tr_shdr
,
142 if (tr_shdr
->type
== TRACE_SHADER_FRAGMENT
) {
143 pipe
->delete_fs_state(pipe
, state
);
144 } else if (tr_shdr
->type
== TRACE_SHADER_VERTEX
) {
145 pipe
->delete_vs_state(pipe
, state
);
150 /************************************************
151 * Request handler functions
156 trace_rbug_texture_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
158 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
159 struct trace_texture
*tr_tex
= NULL
;
161 rbug_texture_t
*texs
;
164 pipe_mutex_lock(tr_scr
->list_mutex
);
165 texs
= MALLOC(tr_scr
->num_textures
* sizeof(rbug_texture_t
));
166 foreach(ptr
, &tr_scr
->textures
) {
167 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
168 texs
[i
++] = VOID2U64(tr_tex
);
170 pipe_mutex_unlock(tr_scr
->list_mutex
);
172 rbug_send_texture_list_reply(tr_rbug
->con
, serial
, texs
, i
, NULL
);
179 trace_rbug_texture_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
181 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
182 struct trace_texture
*tr_tex
;
183 struct rbug_proto_texture_info
*gpti
= (struct rbug_proto_texture_info
*)header
;
185 struct pipe_texture
*t
;
187 pipe_mutex_lock(tr_scr
->list_mutex
);
188 foreach(ptr
, &tr_scr
->textures
) {
189 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
190 if (gpti
->texture
== VOID2U64(tr_tex
))
196 pipe_mutex_unlock(tr_scr
->list_mutex
);
201 rbug_send_texture_info_reply(tr_rbug
->con
, serial
,
202 t
->target
, t
->format
,
203 t
->width
, t
->last_level
+ 1,
204 t
->height
, t
->last_level
+ 1,
205 t
->depth
, t
->last_level
+ 1,
206 t
->block
.width
, t
->block
.height
, t
->block
.size
,
212 pipe_mutex_unlock(tr_scr
->list_mutex
);
218 trace_rbug_texture_read(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
220 struct rbug_proto_texture_read
*gptr
= (struct rbug_proto_texture_read
*)header
;
222 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
223 struct trace_texture
*tr_tex
;
226 struct pipe_screen
*screen
= tr_scr
->screen
;
227 struct pipe_texture
*tex
;
228 struct pipe_transfer
*t
;
232 pipe_mutex_lock(tr_scr
->list_mutex
);
233 foreach(ptr
, &tr_scr
->textures
) {
234 tr_tex
= (struct trace_texture
*)((char*)ptr
- offsetof(struct trace_texture
, list
));
235 if (gptr
->texture
== VOID2U64(tr_tex
))
241 pipe_mutex_unlock(tr_scr
->list_mutex
);
245 tex
= tr_tex
->texture
;
246 t
= screen
->get_tex_transfer(tr_scr
->screen
, tex
,
247 gptr
->face
, gptr
->level
, gptr
->zslice
,
249 gptr
->x
, gptr
->y
, gptr
->w
, gptr
->h
);
251 map
= screen
->transfer_map(screen
, t
);
253 rbug_send_texture_read_reply(tr_rbug
->con
, serial
,
255 t
->block
.width
, t
->block
.height
, t
->block
.size
,
256 (uint8_t*)map
, t
->stride
* t
->nblocksy
,
260 screen
->transfer_unmap(screen
, t
);
261 screen
->tex_transfer_destroy(t
);
263 pipe_mutex_unlock(tr_scr
->list_mutex
);
269 trace_rbug_context_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
271 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
273 struct trace_context
*tr_ctx
= NULL
;
274 rbug_context_t
*ctxs
;
277 pipe_mutex_lock(tr_scr
->list_mutex
);
278 ctxs
= MALLOC(tr_scr
->num_contexts
* sizeof(rbug_context_t
));
279 foreach(ptr
, &tr_scr
->contexts
) {
280 tr_ctx
= (struct trace_context
*)((char*)ptr
- offsetof(struct trace_context
, list
));
281 ctxs
[i
++] = VOID2U64(tr_ctx
);
283 pipe_mutex_unlock(tr_scr
->list_mutex
);
285 rbug_send_context_list_reply(tr_rbug
->con
, serial
, ctxs
, i
, NULL
);
292 trace_rbug_context_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
294 struct rbug_proto_context_info
*info
= (struct rbug_proto_context_info
*)header
;
296 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
297 struct trace_context
*tr_ctx
= NULL
;
298 rbug_texture_t cbufs
[PIPE_MAX_COLOR_BUFS
];
301 pipe_mutex_lock(tr_scr
->list_mutex
);
302 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
305 pipe_mutex_unlock(tr_scr
->list_mutex
);
309 /* protect the pipe context */
310 pipe_mutex_lock(tr_ctx
->draw_mutex
);
311 trace_dump_call_lock();
313 for (i
= 0; i
< tr_ctx
->curr
.nr_cbufs
; i
++)
314 cbufs
[i
] = VOID2U64(tr_ctx
->curr
.cbufs
[i
]);
316 rbug_send_context_info_reply(tr_rbug
->con
, serial
,
317 VOID2U64(tr_ctx
->curr
.vs
), VOID2U64(tr_ctx
->curr
.fs
),
318 cbufs
, tr_ctx
->curr
.nr_cbufs
, VOID2U64(tr_ctx
->curr
.zsbuf
),
319 tr_ctx
->draw_blocker
, tr_ctx
->draw_blocked
, NULL
);
321 trace_dump_call_unlock();
322 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
324 pipe_mutex_unlock(tr_scr
->list_mutex
);
330 trace_rbug_context_draw_block(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
332 struct rbug_proto_context_draw_block
*block
= (struct rbug_proto_context_draw_block
*)header
;
334 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
335 struct trace_context
*tr_ctx
= NULL
;
337 pipe_mutex_lock(tr_scr
->list_mutex
);
338 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, block
->context
);
341 pipe_mutex_unlock(tr_scr
->list_mutex
);
345 pipe_mutex_lock(tr_ctx
->draw_mutex
);
346 tr_ctx
->draw_blocker
|= block
->block
;
347 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
349 pipe_mutex_unlock(tr_scr
->list_mutex
);
355 trace_rbug_context_draw_step(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
357 struct rbug_proto_context_draw_step
*step
= (struct rbug_proto_context_draw_step
*)header
;
359 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
360 struct trace_context
*tr_ctx
= NULL
;
362 pipe_mutex_lock(tr_scr
->list_mutex
);
363 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, step
->context
);
366 pipe_mutex_unlock(tr_scr
->list_mutex
);
370 pipe_mutex_lock(tr_ctx
->draw_mutex
);
371 tr_ctx
->draw_blocked
&= ~step
->step
;
372 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
374 pipe_mutex_unlock(tr_scr
->list_mutex
);
380 trace_rbug_context_draw_unblock(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
382 struct rbug_proto_context_draw_unblock
*unblock
= (struct rbug_proto_context_draw_unblock
*)header
;
384 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
385 struct trace_context
*tr_ctx
= NULL
;
387 pipe_mutex_lock(tr_scr
->list_mutex
);
388 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, unblock
->context
);
391 pipe_mutex_unlock(tr_scr
->list_mutex
);
395 pipe_mutex_lock(tr_ctx
->draw_mutex
);
396 tr_ctx
->draw_blocked
&= ~unblock
->unblock
;
397 tr_ctx
->draw_blocker
&= ~unblock
->unblock
;
398 pipe_mutex_unlock(tr_ctx
->draw_mutex
);
400 pipe_mutex_unlock(tr_scr
->list_mutex
);
406 trace_rbug_context_flush(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
408 struct rbug_proto_context_flush
*flush
= (struct rbug_proto_context_flush
*)header
;
410 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
411 struct trace_context
*tr_ctx
= NULL
;
413 pipe_mutex_lock(tr_scr
->list_mutex
);
414 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, flush
->context
);
417 pipe_mutex_unlock(tr_scr
->list_mutex
);
421 /* protect the pipe context */
422 trace_dump_call_lock();
424 tr_ctx
->pipe
->flush(tr_ctx
->pipe
, flush
->flags
, NULL
);
426 trace_dump_call_unlock();
427 pipe_mutex_unlock(tr_scr
->list_mutex
);
433 trace_rbug_shader_list(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
435 struct rbug_proto_shader_list
*list
= (struct rbug_proto_shader_list
*)header
;
437 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
438 struct trace_context
*tr_ctx
= NULL
;
439 struct trace_shader
*tr_shdr
= NULL
;
441 rbug_shader_t
*shdrs
;
444 pipe_mutex_lock(tr_scr
->list_mutex
);
445 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, list
->context
);
448 pipe_mutex_unlock(tr_scr
->list_mutex
);
452 pipe_mutex_lock(tr_ctx
->list_mutex
);
453 shdrs
= MALLOC(tr_ctx
->num_shaders
* sizeof(rbug_shader_t
));
454 foreach(ptr
, &tr_ctx
->shaders
) {
455 tr_shdr
= (struct trace_shader
*)((char*)ptr
- offsetof(struct trace_shader
, list
));
456 shdrs
[i
++] = VOID2U64(tr_shdr
);
459 pipe_mutex_unlock(tr_ctx
->list_mutex
);
460 pipe_mutex_unlock(tr_scr
->list_mutex
);
462 rbug_send_shader_list_reply(tr_rbug
->con
, serial
, shdrs
, i
, NULL
);
469 trace_rbug_shader_info(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
471 struct rbug_proto_shader_info
*info
= (struct rbug_proto_shader_info
*)header
;
473 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
474 struct trace_context
*tr_ctx
= NULL
;
475 struct trace_shader
*tr_shdr
= NULL
;
476 unsigned original_len
;
477 unsigned replaced_len
;
479 pipe_mutex_lock(tr_scr
->list_mutex
);
480 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, info
->context
);
483 pipe_mutex_unlock(tr_scr
->list_mutex
);
487 pipe_mutex_lock(tr_ctx
->list_mutex
);
489 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, info
->shader
);
492 pipe_mutex_unlock(tr_ctx
->list_mutex
);
493 pipe_mutex_unlock(tr_scr
->list_mutex
);
498 assert(sizeof(struct tgsi_token
) == 4);
500 original_len
= tgsi_num_tokens(tr_shdr
->tokens
);
501 if (tr_shdr
->replaced_tokens
)
502 replaced_len
= tgsi_num_tokens(tr_shdr
->replaced_tokens
);
506 rbug_send_shader_info_reply(tr_rbug
->con
, serial
,
507 (uint32_t*)tr_shdr
->tokens
, original_len
,
508 (uint32_t*)tr_shdr
->replaced_tokens
, replaced_len
,
512 pipe_mutex_unlock(tr_ctx
->list_mutex
);
513 pipe_mutex_unlock(tr_scr
->list_mutex
);
519 trace_rbug_shader_disable(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
521 struct rbug_proto_shader_disable
*dis
= (struct rbug_proto_shader_disable
*)header
;
523 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
524 struct trace_context
*tr_ctx
= NULL
;
525 struct trace_shader
*tr_shdr
= NULL
;
527 pipe_mutex_lock(tr_scr
->list_mutex
);
528 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, dis
->context
);
531 pipe_mutex_unlock(tr_scr
->list_mutex
);
535 pipe_mutex_lock(tr_ctx
->list_mutex
);
537 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, dis
->shader
);
540 pipe_mutex_unlock(tr_ctx
->list_mutex
);
541 pipe_mutex_unlock(tr_scr
->list_mutex
);
545 tr_shdr
->disabled
= dis
->disable
;
547 pipe_mutex_unlock(tr_ctx
->list_mutex
);
548 pipe_mutex_unlock(tr_scr
->list_mutex
);
554 trace_rbug_shader_replace(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
)
556 struct rbug_proto_shader_replace
*rep
= (struct rbug_proto_shader_replace
*)header
;
558 struct trace_screen
*tr_scr
= tr_rbug
->tr_scr
;
559 struct trace_context
*tr_ctx
= NULL
;
560 struct trace_shader
*tr_shdr
= NULL
;
561 struct pipe_context
*pipe
= NULL
;
564 pipe_mutex_lock(tr_scr
->list_mutex
);
565 tr_ctx
= trace_rbug_get_context_locked(tr_scr
, rep
->context
);
568 pipe_mutex_unlock(tr_scr
->list_mutex
);
572 pipe_mutex_lock(tr_ctx
->list_mutex
);
574 tr_shdr
= trace_rbug_get_shader_locked(tr_ctx
, rep
->shader
);
577 pipe_mutex_unlock(tr_ctx
->list_mutex
);
578 pipe_mutex_unlock(tr_scr
->list_mutex
);
582 /* protect the pipe context */
583 trace_dump_call_lock();
587 /* remove old replaced shader */
588 if (tr_shdr
->replaced
) {
589 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
590 trace_shader_bind_locked(pipe
, tr_shdr
, tr_shdr
->state
);
592 FREE(tr_shdr
->replaced_tokens
);
593 trace_shader_delete_locked(pipe
, tr_shdr
, tr_shdr
->replaced
);
594 tr_shdr
->replaced
= NULL
;
595 tr_shdr
->replaced_tokens
= NULL
;
598 /* empty inputs means restore old which we did above */
599 if (rep
->tokens_len
== 0)
602 tr_shdr
->replaced_tokens
= tgsi_dup_tokens((struct tgsi_token
*)rep
->tokens
);
603 if (!tr_shdr
->replaced_tokens
)
606 state
= trace_shader_create_locked(pipe
, tr_shdr
, tr_shdr
->replaced_tokens
);
610 /* bind new shader if the shader is currently a bound */
611 if (tr_ctx
->curr
.fs
== tr_shdr
|| tr_ctx
->curr
.vs
== tr_shdr
)
612 trace_shader_bind_locked(pipe
, tr_shdr
, state
);
615 tr_shdr
->replaced
= state
;
618 trace_dump_call_unlock();
619 pipe_mutex_unlock(tr_ctx
->list_mutex
);
620 pipe_mutex_unlock(tr_scr
->list_mutex
);
625 FREE(tr_shdr
->replaced_tokens
);
626 tr_shdr
->replaced
= NULL
;
627 tr_shdr
->replaced_tokens
= NULL
;
629 trace_dump_call_unlock();
630 pipe_mutex_unlock(tr_ctx
->list_mutex
);
631 pipe_mutex_unlock(tr_scr
->list_mutex
);
636 trace_rbug_header(struct trace_rbug
*tr_rbug
, struct rbug_header
*header
, uint32_t serial
)
640 switch(header
->opcode
) {
642 rbug_send_ping_reply(tr_rbug
->con
, serial
, NULL
);
644 case RBUG_OP_TEXTURE_LIST
:
645 ret
= trace_rbug_texture_list(tr_rbug
, header
, serial
);
647 case RBUG_OP_TEXTURE_INFO
:
648 ret
= trace_rbug_texture_info(tr_rbug
, header
, serial
);
650 case RBUG_OP_TEXTURE_READ
:
651 ret
= trace_rbug_texture_read(tr_rbug
, header
, serial
);
653 case RBUG_OP_CONTEXT_LIST
:
654 ret
= trace_rbug_context_list(tr_rbug
, header
, serial
);
656 case RBUG_OP_CONTEXT_INFO
:
657 ret
= trace_rbug_context_info(tr_rbug
, header
, serial
);
659 case RBUG_OP_CONTEXT_DRAW_BLOCK
:
660 ret
= trace_rbug_context_draw_block(tr_rbug
, header
, serial
);
662 case RBUG_OP_CONTEXT_DRAW_STEP
:
663 ret
= trace_rbug_context_draw_step(tr_rbug
, header
, serial
);
665 case RBUG_OP_CONTEXT_DRAW_UNBLOCK
:
666 ret
= trace_rbug_context_draw_unblock(tr_rbug
, header
, serial
);
668 case RBUG_OP_CONTEXT_FLUSH
:
669 ret
= trace_rbug_context_flush(tr_rbug
, header
, serial
);
671 case RBUG_OP_SHADER_LIST
:
672 ret
= trace_rbug_shader_list(tr_rbug
, header
, serial
);
674 case RBUG_OP_SHADER_INFO
:
675 ret
= trace_rbug_shader_info(tr_rbug
, header
, serial
);
677 case RBUG_OP_SHADER_DISABLE
:
678 ret
= trace_rbug_shader_disable(tr_rbug
, header
);
680 case RBUG_OP_SHADER_REPLACE
:
681 ret
= trace_rbug_shader_replace(tr_rbug
, header
);
684 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__
, header
->opcode
);
688 rbug_free_header(header
);
691 rbug_send_error_reply(tr_rbug
->con
, serial
, ret
, NULL
);
697 trace_rbug_con(struct trace_rbug
*tr_rbug
)
699 struct rbug_header
*header
;
702 debug_printf("%s - connection received\n", __FUNCTION__
);
704 while(tr_rbug
->running
) {
705 header
= rbug_get_message(tr_rbug
->con
, &serial
);
709 if (!trace_rbug_header(tr_rbug
, header
, serial
))
713 debug_printf("%s - connection closed\n", __FUNCTION__
);
715 rbug_disconnect(tr_rbug
->con
);
719 PIPE_THREAD_ROUTINE(trace_rbug_thread
, void_tr_rbug
)
721 struct trace_rbug
*tr_rbug
= void_tr_rbug
;
722 uint16_t port
= 13370;
728 for (;port
<= 13379 && s
< 0; port
++)
729 s
= u_socket_listen_on_port(port
);
732 debug_printf("trace_rbug - failed to listen\n");
736 u_socket_block(s
, false);
738 debug_printf("trace_rbug - remote debugging listening on port %u\n", --port
);
740 while(tr_rbug
->running
) {
743 c
= u_socket_accept(s
);
747 u_socket_block(c
, true);
748 tr_rbug
->con
= rbug_from_socket(c
);
750 trace_rbug_con(tr_rbug
);
762 /**********************************************************
767 trace_rbug_start(struct trace_screen
*tr_scr
)
769 struct trace_rbug
*tr_rbug
= CALLOC_STRUCT(trace_rbug
);
773 tr_rbug
->tr_scr
= tr_scr
;
774 tr_rbug
->running
= TRUE
;
775 tr_rbug
->thread
= pipe_thread_create(trace_rbug_thread
, tr_rbug
);
781 trace_rbug_stop(struct trace_rbug
*tr_rbug
)
786 tr_rbug
->running
= false;
787 pipe_thread_wait(tr_rbug
->thread
);
795 trace_rbug_notify_draw_blocked(struct trace_context
*tr_ctx
)
797 struct trace_screen
*tr_scr
= trace_screen(tr_ctx
->base
.screen
);
798 struct trace_rbug
*tr_rbug
= tr_scr
->rbug
;
800 if (tr_rbug
&& tr_rbug
->con
)
801 rbug_send_context_draw_blocked(tr_rbug
->con
,
802 VOID2U64(tr_ctx
), tr_ctx
->draw_blocked
, NULL
);