phd/src/dash-3d-implementation/js-implementation.tex

118 lines
6.1 KiB
TeX

\fresh{}
\section{JavaScript implementation}
In JavaScript, there is no way of doing parallel computing without using \emph{web workers}.
A web worker is a script in JavaScript that runs in the background, on a separate thread and that can communicate with the main script by sending and receiving messages.
Since our system has many tasks to do, it seems natural to use workers to manage the streaming without impacting the framerate of the renderer.
However, what a worker can do is very limited, since it cannot access the variables of the main script.
Because of this, we are forced to run the renderer on the main script, where it can access the HTML page, and we move all the other tasks to the worker (the access client, the control engine and the segment parsers), and since the main script is the one communicating with the GPU, it will still have to update the model with the parsed content it receives from the worker.
Using the worker does not so much improve the framerate of the system, but it reduces the latency that occurs when receiving a new segment, which can be very frustrating since in a single thread scenario, each time a segment is received, the interface freezes for around half a second.
A sequence diagram of what happens when downloading, parsing and rendering content is shown in Figure~\ref{d3i:sequence}.
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\node at(0, 1) {Main script};
\draw[->, color=LightGray] (0, 0.5) -- (0, -17.5);
\node at(2.5, 1) {Worker};
\draw[->, color=LightGray] (2.5, 0.5) -- (2.5, -17.5);
\node at(10, 1) {Server};
\draw[->, color=LightGray] (10, 0.5) -- (10, -17.5);
% MPD
\draw[color=blue] (0, 0) -- (2.5, -0.1) -- (10, -0.5);
\draw[color=blue, fill=PaleLightBlue] (10, -0.5) -- (10, -1.5) -- (2.5, -2) -- (2.5, -1) -- cycle;
\node[color=blue, rotate=5] at (6.25, -1.25) {Download};
\node[color=blue, above] at(1.25, 0.0) {Ask MPD};
\draw[color=blue, fill=LightBlue] (2.375, -2) rectangle (2.625, -2.9);
\node[color=blue, right=0.2cm] at(2.5, -2.45) {Parse MPD};
\draw[color=blue] (2.5, -2.9) -- (0, -3);
\draw[color=blue, fill=LightBlue] (-0.125, -3.0) rectangle(0.125, -3.5);
\node[color=blue, left=0.2cm] at (0.0, -3.25) {Update model};
% Ask segments
\begin{scope}[shift={(0, -3.5)}]
\draw[color=red] (0, 0) -- (2.5, -0.1);
\node[color=red, above] at(1.25, 0.0) {Ask segment};
\draw[color=red, fill=Pink] (2.375, -0.1) rectangle (2.625, -1);
\node[color=red, right=0.2cm] at (2.5, -0.55) {Compute utilities};
\draw[color=red] (2.5, -1) -- (10, -1.5);
\draw[color=red, fill=PalePink] (10, -1.5) -- (10, -2.5) -- (2.5, -3) -- (2.5, -2) -- cycle;
\node[color=red, rotate=5] at (6.25, -2.25) {Download};
\draw[color=red, fill=Pink] (2.375, -3) rectangle (2.625, -3.9);
\node[color=red, right=0.2cm] at(2.5, -3.45) {Parse segment};
\draw[color=red] (2.5, -3.9) -- (0, -4);
\draw[color=red, fill=Pink] (-0.125, -4.0) rectangle(0.125, -4.5);
\node[color=red, left=0.2cm] at (0.0, -4.25) {Update model};
\end{scope}
% Ask more segments
\begin{scope}[shift={(0, -8)}]
\draw[color=DarkGreen] (0, 0) -- (2.5, -0.1);
\node[color=DarkGreen, above] at(1.25, 0.0) {Ask segment};
\draw[color=DarkGreen, fill=PaleGreen] (2.375, -0.1) rectangle (2.625, -1);
\node[color=DarkGreen, right=0.2cm] at (2.5, -0.55) {Compute utilities};
\draw[color=DarkGreen] (2.5, -1) -- (10, -1.5);
\draw[color=DarkGreen, fill=PalePaleGreen] (10, -1.5) -- (10, -2.5) -- (2.5, -3) -- (2.5, -2) -- cycle;
\node[color=DarkGreen, rotate=5] at (6.25, -2.25) {Download};
\draw[color=DarkGreen, fill=PaleGreen] (2.375, -3) rectangle (2.625, -3.9);
\node[color=DarkGreen, right=0.2cm] at(2.5, -3.45) {Parse segment};
\draw[color=DarkGreen] (2.5, -3.9) -- (0, -4);
\draw[color=DarkGreen, fill=PaleGreen] (-0.125, -4.0) rectangle(0.125, -4.5);
\node[color=DarkGreen, left=0.2cm] at (0.0, -4.25) {Update model};
\end{scope}
% Ask even more segments
\begin{scope}[shift={(0, -12.5)}]
\draw[color=purple] (0, 0) -- (2.5, -0.1);
\node[color=purple, above] at(1.25, 0.0) {Ask segment};
\draw[color=purple, fill=Plum] (2.375, -0.1) rectangle (2.625, -1);
\node[color=purple, right=0.2cm] at (2.5, -0.55) {Compute utilities};
\draw[color=purple] (2.5, -1) -- (10, -1.5);
\draw[color=purple, fill=PalePlum] (10, -1.5) -- (10, -2.5) -- (2.5, -3) -- (2.5, -2) -- cycle;
\node[color=purple, rotate=5] at (6.25, -2.25) {Download};
\draw[color=purple, fill=Plum] (2.375, -3) rectangle (2.625, -3.9);
\node[color=purple, right=0.2cm] at(2.5, -3.45) {Parse segment};
\draw[color=purple] (2.5, -3.9) -- (0, -4);
\draw[color=purple, fill=Plum] (-0.125, -4.0) rectangle(0.125, -4.5);
\node[color=purple, left=0.2cm] at (0.0, -4.25) {Update model};
\end{scope}
\foreach \x in {0,...,5}
{
\draw[color=Goldenrod, fill=LemonChiffon] (-0.125, -\x/2) rectangle (0.125, -\x/2-0.5);
}
\node[color=Goldenrod, left=0.2cm] at (0.0, -1.5) {Render};
\foreach \x in {0,...,7}
{
\draw[color=Goldenrod, fill=LemonChiffon] (-0.125, -\x/2-3.5) rectangle (0.125, -\x/2-4);
\draw[color=Goldenrod, fill=LemonChiffon] (-0.125, -\x/2-8) rectangle (0.125, -\x/2-8.5);
\draw[color=Goldenrod, fill=LemonChiffon] (-0.125, -\x/2-12.5) rectangle (0.125, -\x/2-13);
}
\node[color=Goldenrod, left=0.2cm] at (0.0, -5.5) {Render};
\node[color=Goldenrod, left=0.2cm] at (0.0, -10) {Render};
\node[color=Goldenrod, left=0.2cm] at (0.0, -14.5) {Render};
\end{tikzpicture}
\caption{Repartition of the tasks on the main script and the worker\label{d3i:sequence}}
\end{figure}