1 /**************************************************************************
3 * Copyright 2010 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 VMWARE 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"
40 #include "rbug_context.h"
41 #include "rbug_objects.h"
43 #include "rbug/rbug.h"
47 #define U642VOID(x) ((void *)(unsigned long)(x))
48 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
50 #define container_of(ptr, type, field) \
51 (type*)((char*)ptr - offsetof(type, field))
55 struct rbug_screen *rb_screen;
56 struct rbug_connection *con;
61 PIPE_THREAD_ROUTINE(rbug_thread, void_rbug);
64 /**********************************************************
69 static struct rbug_context *
70 rbug_get_context_locked(struct rbug_screen *rb_screen, rbug_context_t ctx)
72 struct rbug_context *rb_context = NULL;
73 struct rbug_list *ptr;
75 foreach(ptr, &rb_screen->contexts) {
76 rb_context = container_of(ptr, struct rbug_context, list);
77 if (ctx == VOID2U64(rb_context))
85 static struct rbug_shader *
86 rbug_get_shader_locked(struct rbug_context *rb_context, rbug_shader_t shdr)
88 struct rbug_shader *tr_shdr = NULL;
89 struct rbug_list *ptr;
91 foreach(ptr, &rb_context->shaders) {
92 tr_shdr = container_of(ptr, struct rbug_shader, list);
93 if (shdr == VOID2U64(tr_shdr))
102 rbug_shader_create_locked(struct pipe_context *pipe,
103 struct rbug_shader *rb_shader,
104 struct tgsi_token *tokens)
107 struct pipe_shader_state pss = { 0 };
110 switch(rb_shader->type) {
111 case RBUG_SHADER_FRAGMENT:
112 state = pipe->create_fs_state(pipe, &pss);
114 case RBUG_SHADER_VERTEX:
115 state = pipe->create_vs_state(pipe, &pss);
117 case RBUG_SHADER_GEOM:
118 state = pipe->create_gs_state(pipe, &pss);
129 rbug_shader_bind_locked(struct pipe_context *pipe,
130 struct rbug_shader *rb_shader,
133 switch(rb_shader->type) {
134 case RBUG_SHADER_FRAGMENT:
135 pipe->bind_fs_state(pipe, state);
137 case RBUG_SHADER_VERTEX:
138 pipe->bind_vs_state(pipe, state);
140 case RBUG_SHADER_GEOM:
141 pipe->bind_gs_state(pipe, state);
150 rbug_shader_delete_locked(struct pipe_context *pipe,
151 struct rbug_shader *rb_shader,
154 switch(rb_shader->type) {
155 case RBUG_SHADER_FRAGMENT:
156 pipe->delete_fs_state(pipe, state);
158 case RBUG_SHADER_VERTEX:
159 pipe->delete_vs_state(pipe, state);
161 case RBUG_SHADER_GEOM:
162 pipe->delete_gs_state(pipe, state);
170 /************************************************
171 * Request handler functions
176 rbug_texture_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
178 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
179 struct rbug_resource *tr_tex = NULL;
180 struct rbug_list *ptr;
181 rbug_texture_t *texs;
184 pipe_mutex_lock(rb_screen->list_mutex);
185 texs = MALLOC(rb_screen->num_resources * sizeof(rbug_texture_t));
186 foreach(ptr, &rb_screen->resources) {
187 tr_tex = container_of(ptr, struct rbug_resource, list);
188 texs[i++] = VOID2U64(tr_tex);
190 pipe_mutex_unlock(rb_screen->list_mutex);
192 rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL);
199 rbug_texture_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
201 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
202 struct rbug_resource *tr_tex = NULL;
203 struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header;
204 struct rbug_list *ptr;
205 struct pipe_resource *t;
207 pipe_mutex_lock(rb_screen->list_mutex);
208 foreach(ptr, &rb_screen->resources) {
209 tr_tex = container_of(ptr, struct rbug_resource, list);
210 if (gpti->texture == VOID2U64(tr_tex))
216 pipe_mutex_unlock(rb_screen->list_mutex);
220 t = tr_tex->resource;
221 rbug_send_texture_info_reply(tr_rbug->con, serial,
222 t->target, t->format,
226 util_format_get_blockwidth(t->format),
227 util_format_get_blockheight(t->format),
228 util_format_get_blocksize(t->format),
234 pipe_mutex_unlock(rb_screen->list_mutex);
240 rbug_texture_read(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
242 struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
244 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
245 struct rbug_resource *tr_tex = NULL;
246 struct rbug_list *ptr;
248 struct pipe_context *context = rb_screen->private_context;
249 struct pipe_resource *tex;
250 struct pipe_transfer *t;
254 pipe_mutex_lock(rb_screen->list_mutex);
255 foreach(ptr, &rb_screen->resources) {
256 tr_tex = container_of(ptr, struct rbug_resource, list);
257 if (gptr->texture == VOID2U64(tr_tex))
263 pipe_mutex_unlock(rb_screen->list_mutex);
267 tex = tr_tex->resource;
268 t = pipe_get_transfer(context, tex,
269 gptr->level, gptr->face + gptr->zslice,
271 gptr->x, gptr->y, gptr->w, gptr->h);
273 map = context->transfer_map(context, t);
275 rbug_send_texture_read_reply(tr_rbug->con, serial,
277 util_format_get_blockwidth(t->resource->format),
278 util_format_get_blockheight(t->resource->format),
279 util_format_get_blocksize(t->resource->format),
281 t->stride * util_format_get_nblocksy(t->resource->format,
286 context->transfer_unmap(context, t);
287 context->transfer_destroy(context, t);
289 pipe_mutex_unlock(rb_screen->list_mutex);
295 rbug_context_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
297 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
298 struct rbug_list *ptr;
299 struct rbug_context *rb_context = NULL;
300 rbug_context_t *ctxs;
303 pipe_mutex_lock(rb_screen->list_mutex);
304 ctxs = MALLOC(rb_screen->num_contexts * sizeof(rbug_context_t));
305 foreach(ptr, &rb_screen->contexts) {
306 rb_context = container_of(ptr, struct rbug_context, list);
307 ctxs[i++] = VOID2U64(rb_context);
309 pipe_mutex_unlock(rb_screen->list_mutex);
311 rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL);
318 rbug_context_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
320 struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header;
322 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
323 struct rbug_context *rb_context = NULL;
324 rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS];
325 rbug_texture_t texs[PIPE_MAX_SAMPLERS];
328 pipe_mutex_lock(rb_screen->list_mutex);
329 rb_context = rbug_get_context_locked(rb_screen, info->context);
332 pipe_mutex_unlock(rb_screen->list_mutex);
336 /* protect the pipe context */
337 pipe_mutex_lock(rb_context->draw_mutex);
338 pipe_mutex_lock(rb_context->call_mutex);
340 for (i = 0; i < rb_context->curr.nr_cbufs; i++)
341 cbufs[i] = VOID2U64(rb_context->curr.cbufs[i]);
343 for (i = 0; i < rb_context->curr.num_fs_views; i++)
344 texs[i] = VOID2U64(rb_context->curr.fs_texs[i]);
346 rbug_send_context_info_reply(tr_rbug->con, serial,
347 VOID2U64(rb_context->curr.vs), VOID2U64(rb_context->curr.fs),
348 texs, rb_context->curr.num_fs_views,
349 cbufs, rb_context->curr.nr_cbufs,
350 VOID2U64(rb_context->curr.zsbuf),
351 rb_context->draw_blocker, rb_context->draw_blocked, NULL);
353 pipe_mutex_unlock(rb_context->call_mutex);
354 pipe_mutex_unlock(rb_context->draw_mutex);
355 pipe_mutex_unlock(rb_screen->list_mutex);
361 rbug_context_draw_block(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
363 struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header;
365 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
366 struct rbug_context *rb_context = NULL;
368 pipe_mutex_lock(rb_screen->list_mutex);
369 rb_context = rbug_get_context_locked(rb_screen, block->context);
372 pipe_mutex_unlock(rb_screen->list_mutex);
376 pipe_mutex_lock(rb_context->draw_mutex);
377 rb_context->draw_blocker |= block->block;
378 pipe_mutex_unlock(rb_context->draw_mutex);
380 pipe_mutex_unlock(rb_screen->list_mutex);
386 rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
388 struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header;
390 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
391 struct rbug_context *rb_context = NULL;
393 pipe_mutex_lock(rb_screen->list_mutex);
394 rb_context = rbug_get_context_locked(rb_screen, step->context);
397 pipe_mutex_unlock(rb_screen->list_mutex);
401 pipe_mutex_lock(rb_context->draw_mutex);
402 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
403 if (step->step & RBUG_BLOCK_RULE)
404 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
406 rb_context->draw_blocked &= ~step->step;
408 pipe_mutex_unlock(rb_context->draw_mutex);
410 pipe_condvar_broadcast(rb_context->draw_cond);
412 pipe_mutex_unlock(rb_screen->list_mutex);
418 rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
420 struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
422 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
423 struct rbug_context *rb_context = NULL;
425 pipe_mutex_lock(rb_screen->list_mutex);
426 rb_context = rbug_get_context_locked(rb_screen, unblock->context);
429 pipe_mutex_unlock(rb_screen->list_mutex);
433 pipe_mutex_lock(rb_context->draw_mutex);
434 if (rb_context->draw_blocked & RBUG_BLOCK_RULE) {
435 if (unblock->unblock & RBUG_BLOCK_RULE)
436 rb_context->draw_blocked &= ~RBUG_BLOCK_MASK;
438 rb_context->draw_blocked &= ~unblock->unblock;
440 rb_context->draw_blocker &= ~unblock->unblock;
441 pipe_mutex_unlock(rb_context->draw_mutex);
443 pipe_condvar_broadcast(rb_context->draw_cond);
445 pipe_mutex_unlock(rb_screen->list_mutex);
451 rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
453 struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
455 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
456 struct rbug_context *rb_context = NULL;
458 pipe_mutex_lock(rb_screen->list_mutex);
459 rb_context = rbug_get_context_locked(rb_screen, rule->context);
462 pipe_mutex_unlock(rb_screen->list_mutex);
466 pipe_mutex_lock(rb_context->draw_mutex);
467 rb_context->draw_rule.vs = U642VOID(rule->vertex);
468 rb_context->draw_rule.fs = U642VOID(rule->fragment);
469 rb_context->draw_rule.texture = U642VOID(rule->texture);
470 rb_context->draw_rule.surf = U642VOID(rule->surface);
471 rb_context->draw_rule.blocker = rule->block;
472 rb_context->draw_blocker |= RBUG_BLOCK_RULE;
473 pipe_mutex_unlock(rb_context->draw_mutex);
475 pipe_condvar_broadcast(rb_context->draw_cond);
477 pipe_mutex_unlock(rb_screen->list_mutex);
483 rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
485 struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
487 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
488 struct rbug_context *rb_context = NULL;
490 pipe_mutex_lock(rb_screen->list_mutex);
491 rb_context = rbug_get_context_locked(rb_screen, flush->context);
494 pipe_mutex_unlock(rb_screen->list_mutex);
498 /* protect the pipe context */
499 pipe_mutex_lock(rb_context->call_mutex);
501 rb_context->pipe->flush(rb_context->pipe, NULL);
503 pipe_mutex_unlock(rb_context->call_mutex);
504 pipe_mutex_unlock(rb_screen->list_mutex);
510 rbug_shader_list(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
512 struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
514 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
515 struct rbug_context *rb_context = NULL;
516 struct rbug_shader *tr_shdr = NULL;
517 struct rbug_list *ptr;
518 rbug_shader_t *shdrs;
521 pipe_mutex_lock(rb_screen->list_mutex);
522 rb_context = rbug_get_context_locked(rb_screen, list->context);
525 pipe_mutex_unlock(rb_screen->list_mutex);
529 pipe_mutex_lock(rb_context->list_mutex);
530 shdrs = MALLOC(rb_context->num_shaders * sizeof(rbug_shader_t));
531 foreach(ptr, &rb_context->shaders) {
532 tr_shdr = container_of(ptr, struct rbug_shader, list);
533 shdrs[i++] = VOID2U64(tr_shdr);
536 pipe_mutex_unlock(rb_context->list_mutex);
537 pipe_mutex_unlock(rb_screen->list_mutex);
539 rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
546 rbug_shader_info(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
548 struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
550 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
551 struct rbug_context *rb_context = NULL;
552 struct rbug_shader *tr_shdr = NULL;
553 unsigned original_len;
554 unsigned replaced_len;
556 pipe_mutex_lock(rb_screen->list_mutex);
557 rb_context = rbug_get_context_locked(rb_screen, info->context);
560 pipe_mutex_unlock(rb_screen->list_mutex);
564 pipe_mutex_lock(rb_context->list_mutex);
566 tr_shdr = rbug_get_shader_locked(rb_context, info->shader);
569 pipe_mutex_unlock(rb_context->list_mutex);
570 pipe_mutex_unlock(rb_screen->list_mutex);
575 assert(sizeof(struct tgsi_token) == 4);
577 original_len = tgsi_num_tokens(tr_shdr->tokens);
578 if (tr_shdr->replaced_tokens)
579 replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
583 rbug_send_shader_info_reply(tr_rbug->con, serial,
584 (uint32_t*)tr_shdr->tokens, original_len,
585 (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
589 pipe_mutex_unlock(rb_context->list_mutex);
590 pipe_mutex_unlock(rb_screen->list_mutex);
596 rbug_shader_disable(struct rbug_rbug *tr_rbug, struct rbug_header *header)
598 struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
600 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
601 struct rbug_context *rb_context = NULL;
602 struct rbug_shader *tr_shdr = NULL;
604 pipe_mutex_lock(rb_screen->list_mutex);
605 rb_context = rbug_get_context_locked(rb_screen, dis->context);
608 pipe_mutex_unlock(rb_screen->list_mutex);
612 pipe_mutex_lock(rb_context->list_mutex);
614 tr_shdr = rbug_get_shader_locked(rb_context, dis->shader);
617 pipe_mutex_unlock(rb_context->list_mutex);
618 pipe_mutex_unlock(rb_screen->list_mutex);
622 tr_shdr->disabled = dis->disable;
624 pipe_mutex_unlock(rb_context->list_mutex);
625 pipe_mutex_unlock(rb_screen->list_mutex);
631 rbug_shader_replace(struct rbug_rbug *tr_rbug, struct rbug_header *header)
633 struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
635 struct rbug_screen *rb_screen = tr_rbug->rb_screen;
636 struct rbug_context *rb_context = NULL;
637 struct rbug_shader *tr_shdr = NULL;
638 struct pipe_context *pipe = NULL;
641 pipe_mutex_lock(rb_screen->list_mutex);
642 rb_context = rbug_get_context_locked(rb_screen, rep->context);
645 pipe_mutex_unlock(rb_screen->list_mutex);
649 pipe_mutex_lock(rb_context->list_mutex);
651 tr_shdr = rbug_get_shader_locked(rb_context, rep->shader);
654 pipe_mutex_unlock(rb_context->list_mutex);
655 pipe_mutex_unlock(rb_screen->list_mutex);
659 /* protect the pipe context */
660 pipe_mutex_lock(rb_context->call_mutex);
662 pipe = rb_context->pipe;
664 /* remove old replaced shader */
665 if (tr_shdr->replaced_shader) {
666 /* if this shader is bound rebind the original shader */
667 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
668 rbug_shader_bind_locked(pipe, tr_shdr, tr_shdr->shader);
670 FREE(tr_shdr->replaced_tokens);
671 rbug_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced_shader);
672 tr_shdr->replaced_shader = NULL;
673 tr_shdr->replaced_tokens = NULL;
676 /* empty inputs means restore old which we did above */
677 if (rep->tokens_len == 0)
680 tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
681 if (!tr_shdr->replaced_tokens)
684 state = rbug_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
688 /* bind new shader if the shader is currently a bound */
689 if (rb_context->curr.fs == tr_shdr || rb_context->curr.vs == tr_shdr)
690 rbug_shader_bind_locked(pipe, tr_shdr, state);
693 tr_shdr->replaced_shader = state;
696 pipe_mutex_unlock(rb_context->call_mutex);
697 pipe_mutex_unlock(rb_context->list_mutex);
698 pipe_mutex_unlock(rb_screen->list_mutex);
703 FREE(tr_shdr->replaced_tokens);
704 tr_shdr->replaced_shader = NULL;
705 tr_shdr->replaced_tokens = NULL;
707 pipe_mutex_unlock(rb_context->call_mutex);
708 pipe_mutex_unlock(rb_context->list_mutex);
709 pipe_mutex_unlock(rb_screen->list_mutex);
714 rbug_header(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
718 switch(header->opcode) {
720 rbug_send_ping_reply(tr_rbug->con, serial, NULL);
722 case RBUG_OP_TEXTURE_LIST:
723 ret = rbug_texture_list(tr_rbug, header, serial);
725 case RBUG_OP_TEXTURE_INFO:
726 ret = rbug_texture_info(tr_rbug, header, serial);
728 case RBUG_OP_TEXTURE_READ:
729 ret = rbug_texture_read(tr_rbug, header, serial);
731 case RBUG_OP_CONTEXT_LIST:
732 ret = rbug_context_list(tr_rbug, header, serial);
734 case RBUG_OP_CONTEXT_INFO:
735 ret = rbug_context_info(tr_rbug, header, serial);
737 case RBUG_OP_CONTEXT_DRAW_BLOCK:
738 ret = rbug_context_draw_block(tr_rbug, header, serial);
740 case RBUG_OP_CONTEXT_DRAW_STEP:
741 ret = rbug_context_draw_step(tr_rbug, header, serial);
743 case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
744 ret = rbug_context_draw_unblock(tr_rbug, header, serial);
746 case RBUG_OP_CONTEXT_DRAW_RULE:
747 ret = rbug_context_draw_rule(tr_rbug, header, serial);
749 case RBUG_OP_CONTEXT_FLUSH:
750 ret = rbug_context_flush(tr_rbug, header, serial);
752 case RBUG_OP_SHADER_LIST:
753 ret = rbug_shader_list(tr_rbug, header, serial);
755 case RBUG_OP_SHADER_INFO:
756 ret = rbug_shader_info(tr_rbug, header, serial);
758 case RBUG_OP_SHADER_DISABLE:
759 ret = rbug_shader_disable(tr_rbug, header);
761 case RBUG_OP_SHADER_REPLACE:
762 ret = rbug_shader_replace(tr_rbug, header);
765 debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
769 rbug_free_header(header);
772 rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
778 rbug_con(struct rbug_rbug *tr_rbug)
780 struct rbug_header *header;
783 debug_printf("%s - connection received\n", __FUNCTION__);
785 while(tr_rbug->running) {
786 header = rbug_get_message(tr_rbug->con, &serial);
790 if (!rbug_header(tr_rbug, header, serial))
794 debug_printf("%s - connection closed\n", __FUNCTION__);
796 rbug_disconnect(tr_rbug->con);
800 PIPE_THREAD_ROUTINE(rbug_thread, void_tr_rbug)
802 struct rbug_rbug *tr_rbug = void_tr_rbug;
803 uint16_t port = 13370;
809 for (;port <= 13379 && s < 0; port++)
810 s = u_socket_listen_on_port(port);
813 debug_printf("rbug_rbug - failed to listen\n");
817 u_socket_block(s, false);
819 debug_printf("rbug_rbug - remote debugging listening on port %u\n", --port);
821 while(tr_rbug->running) {
824 c = u_socket_accept(s);
828 u_socket_block(c, true);
829 tr_rbug->con = rbug_from_socket(c);
843 /**********************************************************
848 rbug_start(struct rbug_screen *rb_screen)
850 struct rbug_rbug *tr_rbug = CALLOC_STRUCT(rbug_rbug);
854 tr_rbug->rb_screen = rb_screen;
855 tr_rbug->running = TRUE;
856 tr_rbug->thread = pipe_thread_create(rbug_thread, tr_rbug);
862 rbug_stop(struct rbug_rbug *tr_rbug)
867 tr_rbug->running = false;
868 pipe_thread_wait(tr_rbug->thread);
876 rbug_notify_draw_blocked(struct rbug_context *rb_context)
878 struct rbug_screen *rb_screen = rbug_screen(rb_context->base.screen);
879 struct rbug_rbug *tr_rbug = rb_screen->rbug;
881 if (tr_rbug && tr_rbug->con)
882 rbug_send_context_draw_blocked(tr_rbug->con,
883 VOID2U64(rb_context), rb_context->draw_blocked, NULL);