Commit Graph

247 Commits

Author SHA1 Message Date
Yonit Halperin
0bf518cd3d server: set & test channel capabilities in red_channel
The code for setting and testing channel capabilities was
unnecessarily duplicated. Now it is in red_channel.
RedsChannel was dropped from Reds; It was used only for holding
the channels common capabilities, which are now held in RedChannel.
2011-11-02 11:19:48 +02:00
Yonit Halperin
86576aec6a server/red_worker: fix placing of ASSERT(red_channel_client_no_item_being_sent) (fdbz #41523)
Call ASSERT(red_channel_client_no_item_being_sent) only if
red_wait_outgoing_item/s did not timeout.
2011-10-18 15:16:46 +02:00
Christophe Fergeau
6a20050352 replace warning with comment in glz_usr_free_image
When running some xinerama tests, I got several
glz_usr_free_image: error
messages. Looking at the code, this error is reported when this
function is called from a different DisplayChannelClient than the
one which created the glz compressed image.
When this happens, the backtrace is
    at glz_encoder_dictionary.c:362
    0x7fff940b6670) at glz_encoder_dictionary.c:449
    image_type=LZ_IMAGE_TYPE_RGB32, image_width=512, image_height=256, image_stride=2048, first_lines=0x0,
    num_first_lines=0, usr_image_context=0x7fff7420da40, image_head_dist=0x7fff9b2a3194)
    at glz_encoder_dictionary.c:570
    top_down=4, lines=0x0, num_lines=0, stride=2048, io_ptr=0x7fff740ea7c0 "  ZL", num_io_bytes=65536, usr_context=
    0x7fff7420da40, o_enc_dict_context=0x7fff7420da60) at glz_encoder.c:255
    drawable=0x7fff9b46bc08, o_comp_data=0x7fff9b2a3350) at red_worker.c:5753
    0x7fff9b46bc08, can_lossy=0, o_comp_data=0x7fff9b2a3350) at red_worker.c:6211
    0x7fff9b46bc08, can_lossy=0) at red_worker.c:6344
    0x7fff74085c50, dpi=0x7fff7445b890, src_allowed_lossy=0) at red_worker.c:7046
    0x7fff7445b890) at red_worker.c:7720
    at red_worker.c:7964
    at red_worker.c:8431

Since the glz dictionary is shared between all the
DisplayChannelClient instances that belong to the same client, it can
happen that the glz dictionary code decides to free an image from one
thread while it was added from another thread (thread ==
DisplayChannelClient), so the error message that is printed is not an
actual error. This commit removes this message and adds a comment
explaining what's going on.
2011-09-19 18:33:32 +02:00
Christophe Fergeau
011266555a server: fix function prototypes
Several functions in server/ were not specifying an argument list,
ie they were declared as void foo(); When compiling with
-Wstrict-prototypes, this leads to:
test_playback.c:93:5: erreur: function declaration isn’t a prototype
[-Werror=strict-prototypes]
2011-09-05 07:52:20 +02:00
Christophe Fergeau
41174221fb server: init all fields on SpiceMsgDisplayStreamCreate
red_display_marshall_stream_start initializes a
SpiceMsgDisplayStreamCreate structure before marshalling it and
sending it on the wire. However, it never fills
SpiceMsgDisplayStreamCreate::stamp which then causes a complaint
from valgrind. This patch sets this value to 0, it's not used
by the client so the value shouldn't matter.
2011-09-01 03:57:35 +02:00
Yonit Halperin
16ed3f9f25 drawables count for debug 2011-08-23 18:27:53 +03:00
Yonit Halperin
f84dfeb0aa server: registering RedChannel in reds, instead of Channel
Merging the functionality of reds::channel, into RedChannel.
In addition, cleanup and fix disconnection code: before this patch,
red_dispatcher_disconnect_display_client
could have been called from the red_worker thread
(and it must be called only from the io thread).

RedChannel holds only connected channel clients. RedClient holds all the
channel clients that were created till it is destroyed
(and then it destroys them as well).

Note: snd_channel still doesn't use red_channel, however it
creates dummy channel and channel clients, in order to register itself
in reds.

server/red_channel.c: a channel is connected if it holds at least one channel client

Previously I changed RedChannel to hold only connected channel clients and
RedClient, to hold all the channel clients as long as it is not destroyed.

usbredir: multichannel has not been tested, it just compiles.
2011-08-23 18:27:46 +03:00
Yonit Halperin
812d01c060 server/red_channel.c: pack all channel callbacks to ChannelCbs 2011-08-23 18:23:46 +03:00
Alon Levy
67671b2609 server/red_worker: add ref counting to RedDrawable
introduces ref_red_drawable and put_red_drawable (rename from free_red_drawable)

RedDrawable is already references by Drawable and RedGlzDrawable, with
a hack to NULL the drawable field in RedGlzDrawable to indicate RedGlzDrawable
is the last reference holder. Using an explicit reference count instead.
2011-08-23 18:07:10 +03:00
Alon Levy
74ce23a0e8 server/red_worker: add stream_count (for debug purposes) 2011-08-23 18:06:47 +03:00
Alon Levy
11f2ad60ea server/red_worker: validate_surface: print paniced surface_id 2011-08-23 18:06:25 +03:00
Alon Levy
d0e740eeaa server/red_worker: no panic on double destroy primary 2011-08-23 18:06:03 +03:00
Alon Levy
c820b252c1 server/red_worker: DEBUG_CURSORS
Add cursor allocation debugging code that is turned off as long as
DEBUG_CURSORS is not defined.
2011-08-23 18:05:42 +03:00
Alon Levy
f4d07791cc server/red_worker: on_new_display_channel_client: push ack, cleanup
small cleanup patch, only functional change is sending a set ack message.
2011-08-23 18:05:19 +03:00
Alon Levy
969ab70413 server/red_worker: add cursor_channel_client_disconnect
makes RED_WORKER_MESSAGE_CURSOR_DISCONNECT_CLIENT disconnect only a
single client.
2011-08-23 18:04:56 +03:00
Alon Levy
c78e951bff server/red_worker: remove forced disconnect on connect 2011-08-23 18:04:33 +03:00
Yonit Halperin
bed8c9d4f6 server/red_worker.c: fix CursorPipeItem leak
CursorPipeItems and their corresponding cursor_item were not
freed when they were removed from the pipe without sending them.
In addition cursor_channel_hold_pipe_item used wrong conversion
to (CursorItem*) for a (CursorPipeItem*).
2011-08-23 18:04:10 +03:00
Alon Levy
52bff67935 server/red_worker: split cursor pipe item from cursor item
Required to support multiple clients.
Also changes somewhat the way we produce PIPE_ITEM_TYPE_LOCAL_CURSOR. Btw,
I haven't managed to see when we actually produce such an item during my
tests.

Previously we had a single pipe item per CursorItem, this is impossible
with two pipes, which happens when we have two clients.
2011-08-23 18:03:47 +03:00
Alon Levy
24d8340b71 server/red_worker: whitespace fixes 2011-08-23 18:03:24 +03:00
Alon Levy
4db9f1d1a9 server/red_channel: introduce client ring in RedChannel
Also adds Drawable pipes and glz rings.

main_channel and red_worker had several locations that still accessed rcc
directly, so they had to be touched too, but the changes are minimal.

Most changes are in red_channel: drop the single client reference in RedChannel
and add a ring of channels.

Things missing / not done right in red_worker:
 * StreamAgents are in DCC - right/wrong?
 * GlzDict is multiplied - multiple compressions.

We still are missing:
 * remove the disconnect calls on new connections
2011-08-23 18:02:38 +03:00
Alon Levy
6a1d657373 server/red_channel: add pipe_size helpers 2011-08-23 18:02:14 +03:00
Alon Levy
9c192980e8 server/red_worker: remove more direct access to RedChannelClient.rcc 2011-08-23 18:01:51 +03:00
Yonit Halperin
d42575feab server/red_worker.c: make dictionary and cache different per client
There is no inter-client shared dictionary and cache yet.

At this point the display channel can be used by multiple clients.

You can still crash on lack of Drawables or CursorItems due to the slower
clients pipe growing uncontrollably.
2011-08-23 18:01:28 +03:00
Alon Levy
a32e90257e server/red_worker: multiple client support - base split
This patch compiles but breaks spice.

Split both display and cursor channels to a client part and channel part.

Introduce DisplayChannelClient, CursorChannelClient, CommonChannelClient.
don't disconnect channel on client disconnect.
Move all caches to the ChannelClient's.

Remove reference counting of the channel.

No new functionality introduced.

NOTE: Introduces a crash in disconnections, a regression, resulting from
incorrect thread access, that is fixed in the patch titled:
"server: registering RedChannel in reds, instead of Channel"
2011-08-23 18:01:04 +03:00
Alon Levy
406751888e server/red_worker: cleanup 2011-08-23 18:00:41 +03:00
Alon Levy
5bcdf37997 server/main_channel: move latency and bitrate to channel client
They were globals before. This introduces api for other channels
to query the low bandwidth status. The queries themselves are still done
from the wrong context (channel and not channel client) but that's because
the decoupling of channel and channel client will be done in the following
patches.

Note that snd_worker.c got two copied function declarations that belong to
main_channel.h but can't be easily dragged into snd_worker.c since it still
uses it's own RedChannel struct.
2011-08-23 17:57:13 +03:00
Alon Levy
448ed75bd6 server: Add RedClient
That means RedClient tracks a ring of channels. Right now there will be only
a single client because of the disconnection mechanism - whenever a new
client comes we disconnect all existing clients. But this patch adds already
a ring of clients to reds.c (stored in RedServer).

There is a known problem handling many connections and disconnections at the
same time, trigerrable easily by the following script:

export NEW_DISPLAY=:3.0

Xephyr $NEW_DISPLAY -noreset &
for ((i = 0 ; i < 5; ++i)); do
    for ((j = 0 ; j < 10; ++j)); do
        DISPLAY=$NEW_DISPLAY c_win7x86_qxl_tests &
    done
    sleep 2;
done

I fixed a few of the problems resulting from this in the same patch. This
required already introducing a few other changes:
 * make sure all removal of channels happens in the main thread, for that
 two additional dispatcher calls are added to remove a specific channel
 client (RED_WORKER_MESSAGE_CURSOR_DISCONNECT_CLIENT and
 RED_WORKER_MESSAGE_DISPLAY_DISCONNECT_CLIENT).
 * change some asserts in input channel.
 * make main channel disconnect not recursive
 * introduce disconnect call back to red_channel_create_parser

The remaining abort is from a double free in the main channel, still can't
find it (doesn't happen when running under valgrind - probably due to the
slowness resulting from that), but is easy to see when running under gdb.
2011-08-23 17:56:44 +03:00
Alon Levy
2550e825ec server/red_worker: release PIPE_ITEM_TYPE_VERB in display channel
We send a SPICE_MSG_DISPLAY_MARK verb.
2011-08-23 17:46:07 +03:00
Alon Levy
09ae4700d2 server: move pipe from RedChannel to RedChannelClient
Another cleanup patch, no change to behavior (still one client, and it
disconnects previous client if any).

The implementation for multiple client is straightforward: the pipe
remains per (channel,client) pair, so it needs to move from the RedChannel
that to RedChannelClient. Implementation using a single pipe with multiple
consumers (to reflect different latencies) doesn't fit well with pipe rewriting
that is used by the display channel. Additionally this approach is much simpler
to verify. Lastly it doesn't add considerable overhead (but see the display
channel changes in a later patch for a real place to rethink).

This patch is just technical, changing signatures to reflect the first
argument (oop style) so red_channel becomes red_channel_client. Some places
may seem odd but they should be fixed with later comits where the channels
grow to support multiple clients.

Sound (playback/record) channels are the only ones not touched - this is
consistent with previous patches, since they have been left out of the
RedChannel refactoring.  That is left as future work. (note that they don't use
a pipe, which was the reason for not refactoring).
2011-08-23 17:44:54 +03:00
Alon Levy
b6cf68604f server/red_worker: introduce {display,cursor}_is_connected
Instead of checking for worker->{display,cursor}_channel directly.
2011-08-23 17:42:48 +03:00
Alon Levy
7e8e13593e server/red_channel (all): introduce RedChannelClient
This commit adds a RedChannelClient that now owns the stream connection,
but still doesn't own the pipe. There is only a single RCC per RC
right now (and RC still means RedChannel, RedClient will be introduced
later). All internal api changes are in server/red_channel.h, hence
the need to update all channels. red_worker.c is affected the most because
it makes use of direct access to some of RedChannel still.

API changes:

 1. red_channel_client_create added.
  rec_channel_create -> (red_channel_create, red_channel_client_create)
 2. two way connection: rcc->channel, channel->rcc (later channel will
  hold a list, and there will be a RedClient to hold the list of channels
  per client)
 3. seperation of channel disconnect and channel_client_disconnect

TODO:
 usbredir added untested.
2011-08-23 17:42:36 +03:00
Alon Levy
75b6a305ff server/red_worker: drop red_pipe_add_tail, use red_channel_pipe_add_tail
The only difference between them being that the later also does a push.
I don't believe that to be a problem, but if it does I can always introduce
a push'less version.
2011-08-23 17:01:14 +03:00
Alon Levy
8fbc41b717 server/red_channel: renames to use _proc postfix consistently
rename types - we use _proc suffix mostly to indicate function pointer types,
use it for some function pointers that were missing it.

s/channel_handle_migrate_flush_mark/channel_handle_migrate_flush_mark_proc/
s/channel_handle_migrate_data_get_serial/channel_handle_migrate_data_get_serial_proc/
s/channel_handle_migrate_data/channel_handle_migrate_data_proc/
2011-08-23 17:01:14 +03:00
Yonit Halperin
06c2e22fd9 server/red_worker.c: fix - locking the wrong mutex when releasing glz dict 2011-08-23 17:01:14 +03:00
Christophe Fergeau
4b15555fbd mjpeg: fix libjpeg assertion
After the changes to add libjpeg-turbo support to spice-server mjpeg
compression code, it's relatively easy to hit an assertion from
libjpeg in spice-server about "too few scanlines transferred" when
the mjpeg streaming code triggers. This assertion brings down qemu,
which is bad :)

This is because when we first initialize the mjpeg encoder, we do:

stream_width = SPICE_ALIGN(src_rect->right - src_rect->left, 2);
stream_height = SPICE_ALIGN(src_rect->bottom - src_rect->top, 2);

stream->mjpeg_encoder = mjpeg_encoder_new(stream_width, stream_height);

and then when we iterate over the image scanlines to feed them to
libjpeg, we do:

const int image_height = src->bottom - src->top;
const int image_width = src->right - src->left;

for (i = 0; i < image_height; i++) {
    mjpeg_encoder_encode_scanline(...);
}
mjpeg_encoder_end_frame(...);

When stream_height is odd, the mjpeg_encoder will be created with
an height that is 1 more than the number of lines we encode. Then
libjpeg asserts when we tell it we're done with the compression
while it's still waiting for one more scanline.

Looking through git history, this rounding seems to be an artifact
from when we were using ffmpeg for the mjpeg encoding. Since
spicec and spicy (the latter needs a few fixes) can handle streams
with odd height/width, the best way to solve this issue is to stop
rounding up the height and width of the streams we create. This
even saves some bandwidth :)
2011-08-01 11:01:04 +02:00
Christophe Fergeau
b0cd4f4883 red_worker: use new mjpeg_encoder_encode_scanline API
The main point is to move the pixel conversion code into
the MjpegEncoder class to be able to make use libjpeg-turbo
additional pixel formats without the reds_worker code noticing.
2011-07-22 16:53:56 +02:00
Christophe Fergeau
cacca4dce6 red_worker: simplify red_rgb_to_24bpp prototype
It takes a lot of arguments, "id" is unused, "frame" and
"frame_size" can be obtained from the "stream" argument, so
can get rid of 3 arguments to make things more readable.
2011-07-22 16:53:56 +02:00
Christophe Fergeau
1d808d31f4 mjpeg_encoder: rework output buffer allocation
When encoding a frame, red_worker passes an allocated buffer to
libjpeg where it should encode the frame. When it fails, a new
bigger buffer is allocated and the encoding is restarted from
scratch. However, it's possible to use libjpeg to realloc this
buffer if it gets too small during the encoding process. Make use
of this feature, especially since it will make it easier to encore
one line at a time instead of a full frame in subsequent commits.
2011-07-22 16:53:56 +02:00
Christophe Fergeau
22743bee9f red_worker: factor pixel conversion code
When encoding to mjpeg, the on screen data have to be converted
to 24bpp RGB since that's the format that libjpeg expects. Factor
as much code as possible for the 3 formats we handle.
2011-07-22 16:53:56 +02:00
Yonit Halperin
51628f5124 server/red_worker: send surface images to client on-demand after S3/4 wakeup
When surfaces are being reloaded to the worker, we
will send them to the client only if and when it needs them.
2011-07-20 16:00:19 +03:00
Alon Levy
2a4d97fb78 server: add QXLWorker.flush_surfaces_async for S3/S4 support
This does the following, all to remove any referenced memory on the pci bars:
    flush_all_qxl_commands(worker);
    flush_all_surfaces(worker);
    red_wait_outgoing_item((RedChannel *)worker->display_channel);
    red_wait_outgoing_item((RedChannel *)worker->cursor_channel);

The added api is specifically async, i.e. it calls async_complete
when done.
2011-07-20 16:00:19 +03:00
Alon Levy
b26f0532c1 server: add QXLInterface::update_area_complete callback
when update_area_async is called update_area_complete will be called with
the surfaces dirty rectangle list.
2011-07-20 16:00:19 +03:00
Alon Levy
f300de20d9 server/red_worker: handle_dev_input: reuse write_ready introduced for async 2011-07-20 16:00:19 +03:00
Alon Levy
096f49afbf server: add async io support
The new _ASYNC io's in qxl_dev listed at the end get six new api
functions, and an additional callback function "async_complete". When
the async version of a specific io is used, completion is notified by
calling async_complete, and no READY message is written or expected by
the dispatcher.

update_area has been changed to push QXLRects to the worker thread, where
the conversion to SpiceRect takes place.

A cookie has been added to each async call to QXLWorker, and is passed back via
async_complete.

Added api:

QXLWorker:
    update_area_async
    add_memslot_async
    destroy_surfaces_async
    destroy_primary_surface_async
    create_primary_surface_async
    destroy_surface_wait_async

QXLInterface:
    async_complete
2011-07-20 16:00:19 +03:00
Alon Levy
16c844e374 server/red_worker: remove print on handle_dev_destroy_surfaces 2011-07-20 11:08:17 +03:00
Alon Levy
5120dfb284 server/red_worker: *_release_item: less frequent debug messages 2011-07-20 11:08:09 +03:00
Yonit Halperin
00086b8898 server: add missing calls to red_handle_drawable_surfaces_client_synced
red_handle_drawable_surfaces_client_synced was called only from red_pipe_add_drawable, while it
should also be called from red_pipe_add_drawable_after. Otherwise, the client
might receive a command with a reference to a surface it doesn't hold and crash.
2011-07-12 09:01:45 +03:00
Yonit Halperin
686b67473f server: fix access to a released drawable. RHBZ #713474
red_pipe_add_drawable can lead to removal of drawables from current tree
(since it calls red_handle_drawable_surfaces_client_synced), which can
also lead to releasing these drawables.
Before the fix, red_current_add_equal, called red_pipe_add_drawable,
without assuring afterwards that the drawables it refers to are still alive or
still in the current tree.
2011-07-12 09:01:26 +03:00
Yonit Halperin
6d17dbeb0b server: cursor_channel: releasing pipe items resources when the pipe is cleared (on disconnect)
same as commit 74a9d10af96f4d7c8c1b1d7fca124a8df9180787 for cursor channel
2011-07-05 17:23:39 +03:00
Yonit Halperin
6336f9413a server: display_channel: releasing pipe items resources when the pipe is cleared (on disconnect)
fixes "display_channel_release_item: panic: invalid item type"

Before changing the red_worker to use the red_channel interface, there
was a devoted red_pipe_clear routine for the display channel and cursor channel.
However, clearing the pipe in red_channel, uses the release_item callback
the worker provided. This callback has handled only resources that need to be released
after the pipe item was enqueued from the pipe, and only for pipe items that were set in
red_channel_init_send_data.
This fix changes the display channel release_item callback to handle all types of
pipe items, and also handles differently pushed and non-pushed pipe items.
2011-07-05 17:23:39 +03:00