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 "os/os_thread.h"
30 #include "util/u_format.h"
31 #include "util/u_string.h"
32 #include "util/u_inlines.h"
33 #include "util/u_memory.h"
34 #include "util/u_simple_list.h"
35 #include "util/u_network.h"
36 #include "os/os_time.h"
38 #include "tgsi/tgsi_parse.h"
42 #include "tr_texture.h"
44 #include "rbug/rbug.h"
48 #define U642VOID(x) ((void *)(unsigned long)(x))
49 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
53 struct trace_screen *tr_scr;
54 struct rbug_connection *con;
59 PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug);
62 /**********************************************************
67 static struct trace_context *
68 trace_rbug_get_context_locked(struct trace_screen *tr_scr, rbug_context_t ctx)
70 struct trace_context *tr_ctx = NULL;
73 foreach(ptr, &tr_scr->contexts) {
74 tr_ctx = (struct trace_context *)((char*)ptr - offsetof(struct trace_context, list));
75 if (ctx == VOID2U64(tr_ctx))
83 static struct trace_shader *
84 trace_rbug_get_shader_locked(struct trace_context *tr_ctx, rbug_shader_t shdr)
86 struct trace_shader *tr_shdr = NULL;
89 foreach(ptr, &tr_ctx->shaders) {
90 tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list));
91 if (shdr == VOID2U64(tr_shdr))
100 trace_shader_create_locked(struct pipe_context *pipe,
101 struct trace_shader *tr_shdr,
102 struct tgsi_token *tokens)
105 struct pipe_shader_state pss = { 0 };
108 if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
109 state = pipe->create_fs_state(pipe, &pss);
110 } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
111 state = pipe->create_vs_state(pipe, &pss);
119 trace_shader_bind_locked(struct pipe_context *pipe,
120 struct trace_shader *tr_shdr,
123 if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
124 pipe->bind_fs_state(pipe, state);
125 } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
126 pipe->bind_vs_state(pipe, state);
132 trace_shader_delete_locked(struct pipe_context *pipe,
133 struct trace_shader *tr_shdr,
136 if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
137 pipe->delete_fs_state(pipe, state);
138 } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
139 pipe->delete_vs_state(pipe, state);
144 /************************************************
145 * Request handler functions
150 trace_rbug_texture_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
152 struct trace_screen *tr_scr = tr_rbug->tr_scr;
153 struct trace_resource *tr_tex = NULL;
155 rbug_texture_t *texs;
158 pipe_mutex_lock(tr_scr->list_mutex);
159 texs = MALLOC(tr_scr->num_textures * sizeof(rbug_texture_t));
160 foreach(ptr, &tr_scr->textures) {
161 tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list));
162 texs[i++] = VOID2U64(tr_tex);
164 pipe_mutex_unlock(tr_scr->list_mutex);
166 rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL);
173 trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
175 struct trace_screen *tr_scr = tr_rbug->tr_scr;
176 struct trace_resource *tr_tex = NULL;
177 struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header;
179 struct pipe_resource *t;
181 pipe_mutex_lock(tr_scr->list_mutex);
182 foreach(ptr, &tr_scr->textures) {
183 tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list));
184 if (gpti->texture == VOID2U64(tr_tex))
190 pipe_mutex_unlock(tr_scr->list_mutex);
194 t = tr_tex->resource;
195 rbug_send_texture_info_reply(tr_rbug->con, serial,
196 t->target, t->format,
200 util_format_get_blockwidth(t->format),
201 util_format_get_blockheight(t->format),
202 util_format_get_blocksize(t->format),
208 pipe_mutex_unlock(tr_scr->list_mutex);
214 trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
216 struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
218 struct trace_screen *tr_scr = tr_rbug->tr_scr;
219 struct trace_resource *tr_tex = NULL;
222 struct pipe_context *context = tr_scr->private_context;
223 struct pipe_resource *tex;
224 struct pipe_transfer *t;
228 pipe_mutex_lock(tr_scr->list_mutex);
229 foreach(ptr, &tr_scr->textures) {
230 tr_tex = (struct trace_resource *)((char*)ptr - offsetof(struct trace_resource, list));
231 if (gptr->texture == VOID2U64(tr_tex))
237 pipe_mutex_unlock(tr_scr->list_mutex);
241 tex = tr_tex->resource;
242 t = pipe_get_transfer(context, tex,
243 gptr->face, gptr->level, gptr->zslice,
245 gptr->x, gptr->y, gptr->w, gptr->h);
247 map = context->transfer_map(context, t);
249 rbug_send_texture_read_reply(tr_rbug->con, serial,
251 util_format_get_blockwidth(t->resource->format),
252 util_format_get_blockheight(t->resource->format),
253 util_format_get_blocksize(t->resource->format),
255 t->stride * util_format_get_nblocksy(t->resource->format,
260 context->transfer_unmap(context, t);
261 context->transfer_destroy(context, 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];
299 rbug_texture_t texs[PIPE_MAX_SAMPLERS];
302 pipe_mutex_lock(tr_scr->list_mutex);
303 tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context);
306 pipe_mutex_unlock(tr_scr->list_mutex);
310 /* protect the pipe context */
311 pipe_mutex_lock(tr_ctx->draw_mutex);
312 trace_dump_call_lock();
314 for (i = 0; i < tr_ctx->curr.nr_cbufs; i++)
315 cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]);
317 for (i = 0; i < tr_ctx->curr.num_sampler_views; i++)
318 texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]);
320 rbug_send_context_info_reply(tr_rbug->con, serial,
321 VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs),
322 texs, tr_ctx->curr.num_sampler_views,
323 cbufs, tr_ctx->curr.nr_cbufs,
324 VOID2U64(tr_ctx->curr.zsbuf),
325 tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL);
327 trace_dump_call_unlock();
328 pipe_mutex_unlock(tr_ctx->draw_mutex);
330 pipe_mutex_unlock(tr_scr->list_mutex);
336 trace_rbug_context_draw_block(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
338 struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header;
340 struct trace_screen *tr_scr = tr_rbug->tr_scr;
341 struct trace_context *tr_ctx = NULL;
343 pipe_mutex_lock(tr_scr->list_mutex);
344 tr_ctx = trace_rbug_get_context_locked(tr_scr, block->context);
347 pipe_mutex_unlock(tr_scr->list_mutex);
351 pipe_mutex_lock(tr_ctx->draw_mutex);
352 tr_ctx->draw_blocker |= block->block;
353 pipe_mutex_unlock(tr_ctx->draw_mutex);
355 pipe_mutex_unlock(tr_scr->list_mutex);
361 trace_rbug_context_draw_step(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
363 struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header;
365 struct trace_screen *tr_scr = tr_rbug->tr_scr;
366 struct trace_context *tr_ctx = NULL;
368 pipe_mutex_lock(tr_scr->list_mutex);
369 tr_ctx = trace_rbug_get_context_locked(tr_scr, step->context);
372 pipe_mutex_unlock(tr_scr->list_mutex);
376 pipe_mutex_lock(tr_ctx->draw_mutex);
377 if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) {
378 if (step->step & RBUG_BLOCK_RULE)
379 tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK;
381 tr_ctx->draw_blocked &= ~step->step;
383 pipe_mutex_unlock(tr_ctx->draw_mutex);
385 #ifdef PIPE_THREAD_HAVE_CONDVAR
386 pipe_condvar_broadcast(tr_ctx->draw_cond);
389 pipe_mutex_unlock(tr_scr->list_mutex);
395 trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
397 struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
399 struct trace_screen *tr_scr = tr_rbug->tr_scr;
400 struct trace_context *tr_ctx = NULL;
402 pipe_mutex_lock(tr_scr->list_mutex);
403 tr_ctx = trace_rbug_get_context_locked(tr_scr, unblock->context);
406 pipe_mutex_unlock(tr_scr->list_mutex);
410 pipe_mutex_lock(tr_ctx->draw_mutex);
411 if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) {
412 if (unblock->unblock & RBUG_BLOCK_RULE)
413 tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK;
415 tr_ctx->draw_blocked &= ~unblock->unblock;
417 tr_ctx->draw_blocker &= ~unblock->unblock;
418 pipe_mutex_unlock(tr_ctx->draw_mutex);
420 #ifdef PIPE_THREAD_HAVE_CONDVAR
421 pipe_condvar_broadcast(tr_ctx->draw_cond);
424 pipe_mutex_unlock(tr_scr->list_mutex);
430 trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
432 struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
434 struct trace_screen *tr_scr = tr_rbug->tr_scr;
435 struct trace_context *tr_ctx = NULL;
437 pipe_mutex_lock(tr_scr->list_mutex);
438 tr_ctx = trace_rbug_get_context_locked(tr_scr, rule->context);
441 pipe_mutex_unlock(tr_scr->list_mutex);
445 pipe_mutex_lock(tr_ctx->draw_mutex);
446 tr_ctx->draw_rule.vs = U642VOID(rule->vertex);
447 tr_ctx->draw_rule.fs = U642VOID(rule->fragment);
448 tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture);
449 tr_ctx->draw_rule.surf = U642VOID(rule->surface);
450 tr_ctx->draw_rule.blocker = rule->block;
451 tr_ctx->draw_blocker |= RBUG_BLOCK_RULE;
452 pipe_mutex_unlock(tr_ctx->draw_mutex);
454 #ifdef PIPE_THREAD_HAVE_CONDVAR
455 pipe_condvar_broadcast(tr_ctx->draw_cond);
458 pipe_mutex_unlock(tr_scr->list_mutex);
464 trace_rbug_context_flush(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
466 struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
468 struct trace_screen *tr_scr = tr_rbug->tr_scr;
469 struct trace_context *tr_ctx = NULL;
471 pipe_mutex_lock(tr_scr->list_mutex);
472 tr_ctx = trace_rbug_get_context_locked(tr_scr, flush->context);
475 pipe_mutex_unlock(tr_scr->list_mutex);
479 /* protect the pipe context */
480 trace_dump_call_lock();
482 tr_ctx->pipe->flush(tr_ctx->pipe, flush->flags, NULL);
484 trace_dump_call_unlock();
485 pipe_mutex_unlock(tr_scr->list_mutex);
491 trace_rbug_shader_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
493 struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
495 struct trace_screen *tr_scr = tr_rbug->tr_scr;
496 struct trace_context *tr_ctx = NULL;
497 struct trace_shader *tr_shdr = NULL;
499 rbug_shader_t *shdrs;
502 pipe_mutex_lock(tr_scr->list_mutex);
503 tr_ctx = trace_rbug_get_context_locked(tr_scr, list->context);
506 pipe_mutex_unlock(tr_scr->list_mutex);
510 pipe_mutex_lock(tr_ctx->list_mutex);
511 shdrs = MALLOC(tr_ctx->num_shaders * sizeof(rbug_shader_t));
512 foreach(ptr, &tr_ctx->shaders) {
513 tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list));
514 shdrs[i++] = VOID2U64(tr_shdr);
517 pipe_mutex_unlock(tr_ctx->list_mutex);
518 pipe_mutex_unlock(tr_scr->list_mutex);
520 rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
527 trace_rbug_shader_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
529 struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
531 struct trace_screen *tr_scr = tr_rbug->tr_scr;
532 struct trace_context *tr_ctx = NULL;
533 struct trace_shader *tr_shdr = NULL;
534 unsigned original_len;
535 unsigned replaced_len;
537 pipe_mutex_lock(tr_scr->list_mutex);
538 tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context);
541 pipe_mutex_unlock(tr_scr->list_mutex);
545 pipe_mutex_lock(tr_ctx->list_mutex);
547 tr_shdr = trace_rbug_get_shader_locked(tr_ctx, info->shader);
550 pipe_mutex_unlock(tr_ctx->list_mutex);
551 pipe_mutex_unlock(tr_scr->list_mutex);
556 assert(sizeof(struct tgsi_token) == 4);
558 original_len = tgsi_num_tokens(tr_shdr->tokens);
559 if (tr_shdr->replaced_tokens)
560 replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
564 rbug_send_shader_info_reply(tr_rbug->con, serial,
565 (uint32_t*)tr_shdr->tokens, original_len,
566 (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
570 pipe_mutex_unlock(tr_ctx->list_mutex);
571 pipe_mutex_unlock(tr_scr->list_mutex);
577 trace_rbug_shader_disable(struct trace_rbug *tr_rbug, struct rbug_header *header)
579 struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
581 struct trace_screen *tr_scr = tr_rbug->tr_scr;
582 struct trace_context *tr_ctx = NULL;
583 struct trace_shader *tr_shdr = NULL;
585 pipe_mutex_lock(tr_scr->list_mutex);
586 tr_ctx = trace_rbug_get_context_locked(tr_scr, dis->context);
589 pipe_mutex_unlock(tr_scr->list_mutex);
593 pipe_mutex_lock(tr_ctx->list_mutex);
595 tr_shdr = trace_rbug_get_shader_locked(tr_ctx, dis->shader);
598 pipe_mutex_unlock(tr_ctx->list_mutex);
599 pipe_mutex_unlock(tr_scr->list_mutex);
603 tr_shdr->disabled = dis->disable;
605 pipe_mutex_unlock(tr_ctx->list_mutex);
606 pipe_mutex_unlock(tr_scr->list_mutex);
612 trace_rbug_shader_replace(struct trace_rbug *tr_rbug, struct rbug_header *header)
614 struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
616 struct trace_screen *tr_scr = tr_rbug->tr_scr;
617 struct trace_context *tr_ctx = NULL;
618 struct trace_shader *tr_shdr = NULL;
619 struct pipe_context *pipe = NULL;
622 pipe_mutex_lock(tr_scr->list_mutex);
623 tr_ctx = trace_rbug_get_context_locked(tr_scr, rep->context);
626 pipe_mutex_unlock(tr_scr->list_mutex);
630 pipe_mutex_lock(tr_ctx->list_mutex);
632 tr_shdr = trace_rbug_get_shader_locked(tr_ctx, rep->shader);
635 pipe_mutex_unlock(tr_ctx->list_mutex);
636 pipe_mutex_unlock(tr_scr->list_mutex);
640 /* protect the pipe context */
641 trace_dump_call_lock();
645 /* remove old replaced shader */
646 if (tr_shdr->replaced) {
647 if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr)
648 trace_shader_bind_locked(pipe, tr_shdr, tr_shdr->state);
650 FREE(tr_shdr->replaced_tokens);
651 trace_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced);
652 tr_shdr->replaced = NULL;
653 tr_shdr->replaced_tokens = NULL;
656 /* empty inputs means restore old which we did above */
657 if (rep->tokens_len == 0)
660 tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
661 if (!tr_shdr->replaced_tokens)
664 state = trace_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
668 /* bind new shader if the shader is currently a bound */
669 if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr)
670 trace_shader_bind_locked(pipe, tr_shdr, state);
673 tr_shdr->replaced = state;
676 trace_dump_call_unlock();
677 pipe_mutex_unlock(tr_ctx->list_mutex);
678 pipe_mutex_unlock(tr_scr->list_mutex);
683 FREE(tr_shdr->replaced_tokens);
684 tr_shdr->replaced = NULL;
685 tr_shdr->replaced_tokens = NULL;
687 trace_dump_call_unlock();
688 pipe_mutex_unlock(tr_ctx->list_mutex);
689 pipe_mutex_unlock(tr_scr->list_mutex);
694 trace_rbug_header(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
698 switch(header->opcode) {
700 rbug_send_ping_reply(tr_rbug->con, serial, NULL);
702 case RBUG_OP_TEXTURE_LIST:
703 ret = trace_rbug_texture_list(tr_rbug, header, serial);
705 case RBUG_OP_TEXTURE_INFO:
706 ret = trace_rbug_texture_info(tr_rbug, header, serial);
708 case RBUG_OP_TEXTURE_READ:
709 ret = trace_rbug_texture_read(tr_rbug, header, serial);
711 case RBUG_OP_CONTEXT_LIST:
712 ret = trace_rbug_context_list(tr_rbug, header, serial);
714 case RBUG_OP_CONTEXT_INFO:
715 ret = trace_rbug_context_info(tr_rbug, header, serial);
717 case RBUG_OP_CONTEXT_DRAW_BLOCK:
718 ret = trace_rbug_context_draw_block(tr_rbug, header, serial);
720 case RBUG_OP_CONTEXT_DRAW_STEP:
721 ret = trace_rbug_context_draw_step(tr_rbug, header, serial);
723 case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
724 ret = trace_rbug_context_draw_unblock(tr_rbug, header, serial);
726 case RBUG_OP_CONTEXT_DRAW_RULE:
727 ret = trace_rbug_context_draw_rule(tr_rbug, header, serial);
729 case RBUG_OP_CONTEXT_FLUSH:
730 ret = trace_rbug_context_flush(tr_rbug, header, serial);
732 case RBUG_OP_SHADER_LIST:
733 ret = trace_rbug_shader_list(tr_rbug, header, serial);
735 case RBUG_OP_SHADER_INFO:
736 ret = trace_rbug_shader_info(tr_rbug, header, serial);
738 case RBUG_OP_SHADER_DISABLE:
739 ret = trace_rbug_shader_disable(tr_rbug, header);
741 case RBUG_OP_SHADER_REPLACE:
742 ret = trace_rbug_shader_replace(tr_rbug, header);
745 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
749 rbug_free_header(header);
752 rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
758 trace_rbug_con(struct trace_rbug *tr_rbug)
760 struct rbug_header *header;
763 debug_printf("%s - connection received\n", __FUNCTION__);
765 while(tr_rbug->running) {
766 header = rbug_get_message(tr_rbug->con, &serial);
770 if (!trace_rbug_header(tr_rbug, header, serial))
774 debug_printf("%s - connection closed\n", __FUNCTION__);
776 rbug_disconnect(tr_rbug->con);
780 PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug)
782 struct trace_rbug *tr_rbug = void_tr_rbug;
783 uint16_t port = 13370;
789 for (;port <= 13379 && s < 0; port++)
790 s = u_socket_listen_on_port(port);
793 debug_printf("trace_rbug - failed to listen\n");
797 u_socket_block(s, false);
799 debug_printf("trace_rbug - remote debugging listening on port %u\n", --port);
801 while(tr_rbug->running) {
804 c = u_socket_accept(s);
808 u_socket_block(c, true);
809 tr_rbug->con = rbug_from_socket(c);
811 trace_rbug_con(tr_rbug);
823 /**********************************************************
828 trace_rbug_start(struct trace_screen *tr_scr)
830 struct trace_rbug *tr_rbug = CALLOC_STRUCT(trace_rbug);
834 tr_rbug->tr_scr = tr_scr;
835 tr_rbug->running = TRUE;
836 tr_rbug->thread = pipe_thread_create(trace_rbug_thread, tr_rbug);
842 trace_rbug_stop(struct trace_rbug *tr_rbug)
847 tr_rbug->running = false;
848 pipe_thread_wait(tr_rbug->thread);
856 trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx)
858 struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);
859 struct trace_rbug *tr_rbug = tr_scr->rbug;
861 if (tr_rbug && tr_rbug->con)
862 rbug_send_context_draw_blocked(tr_rbug->con,
863 VOID2U64(tr_ctx), tr_ctx->draw_blocked, NULL);