vc-1: Add platform-specific start code search routine to VC1DSPContext.

Initialise VC1DSPContext for parser as well as for decoder.
Note, the VC-1 code doesn't actually use the function pointer yet.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
vc-1: Optimise parser (with special attention to ARM)

The previous implementation of the parser made four passes over each input
buffer (reduced to two if the container format already guaranteed the input
buffer corresponded to frames, such as with MKV). But these buffers are
often 200K in size, certainly enough to flush the data out of L1 cache, and
for many CPUs, all the way out to main memory. The passes were:

1) locate frame boundaries (not needed for MKV etc)
2) copy the data into a contiguous block (not needed for MKV etc)
3) locate the start codes within each frame
4) unescape the data between start codes

After this, the unescaped data was parsed to extract certain header fields,
but because the unescape operation was so large, this was usually also
effectively operating on uncached memory. Most of the unescaped data was
simply thrown away and never processed further. Only step 2 - because it
used memcpy - was using prefetch, making things even worse.

This patch reorganises these steps so that, aside from the copying, the
operations are performed in parallel, maximising cache utilisation. No more
than the worst-case number of bytes needed for header parsing is unescaped.
Most of the data is, in practice, only read in order to search for a start
code, for which optimised implementations already existed in the H264 codec
(notably the ARM version uses prefetch, so we end up doing both remaining
passes at maximum speed). For MKV files, we know when we've found the last
start code of interest in a given frame, so we are able to avoid doing even
that one remaining pass for most of the buffer.

In some use-cases (such as the Raspberry Pi) video decode is handled by the
GPU, but the entire elementary stream is still fed through the parser to
pick out certain elements of the header which are necessary to manage the
decode process. As you might expect, in these cases, the performance of the
parser is significant.

To measure parser performance, I used the same VC-1 elementary stream in
either an MPEG-2 transport stream or a MKV file, and fed it through ffmpeg
with -c:v copy -c:a copy -f null. These are the gperftools counts for
those streams, both filtered to only include vc1_parse() and its callees,
and unfiltered (to include the whole binary). Lower numbers are better:

                Before          After
File  Filtered  Mean   StdDev   Mean   StdDev  Confidence  Change
M2TS  No        861.7  8.2      650.5  8.1     100.0%      +32.5%
MKV   No        868.9  7.4      731.7  9.0     100.0%      +18.8%
M2TS  Yes       250.0  11.2     27.2   3.4     100.0%      +817.9%
MKV   Yes       149.0  12.8     1.7    0.8     100.0%      +8526.3%

Yes, that last case shows vc1_parse() running 86 times faster! The M2TS
case does show a larger absolute improvement though, since it was worse
to begin with.

This patch has been tested with the FATE suite (albeit on x86 for speed).

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
 truehd: add hand-scheduled ARM asm version of mlp_filter_channel.

Profiling results for overall audio decode and the mlp_filter_channel(_arm)
function in particular are as follows:

              Before          After
              Mean   StdDev   Mean   StdDev  Confidence  Change
6:2 total     380.4  22.0     370.8  17.0    87.4%       +2.6%  (insignificant)
6:2 function  60.7   7.2      36.6   8.1     100.0%      +65.8%
8:2 total     357.0  17.5     343.2  19.0    97.8%       +4.0%  (insignificant)
8:2 function  60.3   8.8      37.3   3.8     100.0%      +61.8%
6:6 total     717.2  23.2     658.4  15.7    100.0%      +8.9%
6:6 function  140.4  12.9     81.5   9.2     100.0%      +72.4%
8:8 total     981.9  16.2     896.2  24.5    100.0%      +9.6%
8:8 function  193.4  15.0     103.3  11.5    100.0%      +87.2%

Experiments with adding preload instructions to this function yielded no
useful benefit, so these have not been included.

The assembly version has also been tested with a fuzz tester to ensure that
any combinations of inputs not exercised by my available test streams still
generate mathematically identical results to the C version.
truehd: break out part of rematrix_channels into platform-specific callback.

Verified with profiling that this doesn't have a measurable effect upon
overall performance.
truehd: add hand-scheduled ARM asm version of ff_mlp_rematrix_channel.

Profiling results for overall audio decode and the rematrix_channels function
in particular are as follows:

              Before          After
              Mean   StdDev   Mean   StdDev  Confidence  Change
6:2 total     370.8  17.0     348.8  20.1    99.9%       +6.3%
6:2 function  46.4   8.4      45.8   6.6     18.0%       +1.2%  (insignificant)
8:2 total     343.2  19.0     339.1  15.4    54.7%       +1.2%  (insignificant)
8:2 function  38.9   3.9      40.2   6.9     52.4%       -3.2%  (insignificant)
6:6 total     658.4  15.7     604.6  20.8    100.0%      +8.9%
6:6 function  109.0  8.7      59.5   5.4     100.0%      +83.3%
8:8 total     896.2  24.5     766.4  17.6    100.0%      +16.9%
8:8 function  223.4  12.8     93.8   5.0     100.0%      +138.3%

The assembly version has also been tested with a fuzz tester to ensure that
any combinations of inputs not exercised by my available test streams still
generate mathematically identical results to the C version.
truehd: tune VLC decoding for ARM.

Profiling on a Raspberry Pi revealed the best performance to correspond
with VLC_BITS = 5. Results for overall audio decode and the get_vlc2 function
in particular are as follows:

              Before          After
              Mean   StdDev   Mean   StdDev  Confidence  Change
6:2 total     348.8  20.1     339.6  15.1    88.8%       +2.7%  (insignificant)
6:2 function  38.1   8.1      26.4   4.1     100.0%      +44.5%
8:2 total     339.1  15.4     324.5  15.5    99.4%       +4.5%
8:2 function  33.8   7.0      27.3   5.6     99.7%       +23.6%
6:6 total     604.6  20.8     572.8  20.6    100.0%      +5.6%
6:6 function  95.8   8.4      68.9   8.2     100.0%      +39.1%
8:8 total     766.4  17.6     741.5  21.2    100.0%      +3.4%
8:8 function  106.0  11.4     86.1   9.9     100.0%      +23.1%
truehd: break out part of output_data into platform-specific callback.

Verified with profiling that this doesn't have a measurable effect upon
overall performance.
truehd: add hand-scheduled ARM asm version of ff_mlp_pack_output.

Profiling results for overall decode and the output_data function in
particular are as follows:

              Before          After
              Mean   StdDev   Mean   StdDev  Confidence  Change
6:2 total     339.6  15.1     329.3  16.0    95.8%       +3.1%  (insignificant)
6:2 function  24.6   6.0      9.9    3.1     100.0%      +148.5%
8:2 total     324.5  15.5     323.6  14.3    15.2%       +0.3%  (insignificant)
8:2 function  20.4   3.9      9.9    3.4     100.0%      +104.7%
6:6 total     572.8  20.6     539.9  24.2    100.0%      +6.1%
6:6 function  54.5   5.6      16.0   3.8     100.0%      +240.9%
8:8 total     741.5  21.2     702.5  18.5    100.0%      +5.6%
8:8 function  63.9   7.6      18.4   4.8     100.0%      +247.3%

The assembly version has also been tested with a fuzz tester to ensure that
any combinations of inputs not exercised by my available test streams still
generate mathematically identical results to the C version.
More efficient infobool expression evaluator

Expession infobools are evaluated at runtime from one or more single infobools
and a combination of boolean NOT, AND and OR operators. Previously, parsing
produced a vector of operands (leaf nodes) and operators in postfix
(reverse-Polish) form, and evaluated all leaf nodes every time the expression
was evaluated. But this ignores the fact that in many cases, once one operand
of an AND or OR operation has been evaluated, there is no need to evaluate the
other operand because its value can have no effect on the ultimate result. It
is also worth noting that AND and OR operations are associative, meaning they
can be rearranged at runtime to better suit the selected skin.

This patch rewrites the expression parsing and evaluation code. Now the
internal repreentation is in the form of a tree where leaf nodes represent a
single infobool, and branch nodes represent either an AND or an OR operation
on two or more child nodes.

Expressions are rewritten at parse time into a form which favours the
formation of groups of associative nodes. These groups are then reordered at
evaluation time such that nodes whose value renders the evaluation of the
remainder of the group unnecessary tend to be evaluated first (these are
true nodes for OR subexpressions, or false nodes for AND subexpressions).
The end effect is to minimise the number of leaf nodes that need to be
evaluated in order to determine the value of the expression. The runtime
adaptability has the advantage of not being customised for any particular skin.

The modifications to the expression at parse time fall into two groups:
1) Moving logical NOTs so that they are only applied to leaf nodes.
   For example, rewriting ![A+B]|C as !A|!B|C allows reordering such that
   any of the three leaves can be evaluated first.
2) Combining adjacent AND or OR operations such that each path from the root
   to a leaf encounters a strictly alternating pattern of AND and OR
   operations. So [A|B]|[C|D+[[E|F]|G] becomes A|B|C|[D+[E|F|G]].

I measured the effect while the Videos window of the default skin was open
(but idle) on a Raspberry Pi, and this reduced the CPU usage by 2.8% from
41.9% to 39.1%:

          Before          After
          Mean   StdDev   Mean   StdDev  Confidence  Change
IdleCPU%  41.9   0.5      39.1   0.9     100.0%      +7.0%
Where an infobool expression failed to parse, evaluate the infobool as false. Previously, this would result in a segfault due to the dereferencing of an uninitialised pointer to the head of the expression tree.
Add caching of infolabels

The functions CGUIInfoLabel::GetLabel and CGUIInfoLabel::GetItemLabel take
a number of strings returned from CGUIInfoManager::GetImage or
CGUIInfoManager::GetLabel, and combine them with various constant strings
which were determined during CGUIInfoLabel::Parse.

Rather than perform all the string operations on every call, this patch
changes to use a two-pass process: first it queries all the GetImage/GetLabel
strings, and then only if at least one of them has changed does it bother
rebuilding the resultant string - otherwise it re-uses the copy built on a
preceding call.

CGUIInfoLabel::GetLabel/GetItemLabel are also changed to return string
references, rather than forcing an additional string copy.

I have measured the effect while the Videos window of the default skin was
open (but idle) on a Raspberry Pi, and this reduced the CPU usage by 0.8%
from 36.2% to 35.4%:

          Before          After
          Mean   StdDev   Mean   StdDev  Confidence  Change
IdleCPU%  36.2   0.5      35.4   0.5     99.9%       +2.2%
De-duplication of string cache for non-item and item labels
Faster and simpler portable implementation of MathUtils::round_int().

Much as I like a bit of inline assembler, I have also removed the ARM versions
of MathUtils::truncate_int() and MathUtils::round_int(). The former was just
how any sane compiler should have assembled a cast from double to signed int
anyway. The latter was a much too complicated way to achieve the desired
effect, and was switched out in most ARM builds anyway in favour of the old
portable implementation that used floor().

Verified that MathUtils::test() still passes, and that GCC is now able to
inline MathUtils::round_int(), where it didn't previously.

I tested on a Raspberry Pi with the default theme, displaying the front page
with the RSS ticker enabled. This saturates the CPU, so I'm measuring the
improvement using the debug window's FPS figure. This patch improves this from
~50.8 FPS to ~52.6 FPS.
Move the reference-counting of Begin and End calls from DX and GL source files into GUIFontTTF.cpp.
Convert CGUIFontTTFBase::m_vertex to be managed as a std::vector. Also retired CGUIFontTTFBase::m_vertex_count and CGUIFontTTFBase::m_vertex_size because these can be derived from vector member functions.
CGUIFontTTFBase::RenderCharacter can now append to arbitrary vectors of vertices rather than only CGUIFontTTFBase::m_vertex
Add a cache of font glyph bounding box vertices. This is implemented as a template because ultimately we will key on different parameters and store values of different types, depending upon whether we have a GLES or non-GLES backend, and for GLES, whether or not the currently applicable transformation matrices permit the use of hardware clipping.
Lay the groundwork for hardware clipping.

For glScissor() to replace CGraphicContext::ClipRect, a necessary condition
is that no shear or rotation is introduced between the coordinate systems
they use; this depends upon the settings of the GUI matrix m_finalTransform
as well as the OpenGL model-view and projection matrices. These all remain
unchanged between paired calls of CGUIShader::OnEnabled and
CGUIShader::OnDisabled, so we scan the matrices in CGUIShader::OnEnabled to
see whether hardware clipping is possible.

Then, in CGUIFontTTFBase::RenderCharacter, we don't apply software clipping
in such cases. However, because vertices arising from multiple
CGUIFontTTFBase::DrawTextInternal calls (each of which often uses a different
clip rectangle) get lumped into the same vector, which only at the end is
passed to OpenGL for rendering, we need to wait a few commits before we can
actually apply hardware clipping. In the meantime, expect to see rendering
errors.
Increase font cache hit rate by keying on the fractional part of m_originX and m_originY *after* they have been through the graphics context's transformation matrix, plus the scale/rotation elements of the matrix, rather than the origin in the original frame of reference plus the complete transformation matrix. All vertices of individual glyph bounding boxes are a constant offset from this position, and when the fractional part of the translation is a match, the rounding of each vertex will be in the same direction; this permits us to calculate the desired vertices from the cached ones simply by adding the integer parts of the translations with no additional rounding steps.

Note that this requires that software clipping is *not* performed.
Rewrite of scrolling text code.

No longer shuffles the string round to minimise the number of characters
before the clipping rectangle; this doesn't save much on rendering time but
does harm the effectiveness of the cache. Now uses a pixel offset into the
string rather than a character + pixel offset, and plots the entire string
every time (execpt when the wrap point is visible, in which case the entire
string is plotted twice).

It also makes motion smoother, because (possibly unintentionally) the
previous code preferred to align the scroll offset with character boundaries.
This would lead to uneven changes of position, especially when the width of
the character currently being scrolled off the edge was only slightly more
than an integral multiple of the scroll increment.