Commit Graph

59437 Commits

Author SHA1 Message Date
Eric Anholt
4e54751624 dri: Implement a DRI vtable extension to replace the global driDriverAPI.
As we move to megadrivers, we are unable to build multiple drivers with
the same public global symbol per driver (Think an X Server with an intel
and a nouveau driver, and the X Server implementing indirect for both --
we have to actually talk to the right driver).  By slipping the
driDriverAPI vtable into the driver's extension list, we can replace the
usage of the global symbol with usage of the loader-dlsym()ed driver
information.

v2: Pull in the hunk to avoid crashing on null driver_extensions.  Thanks,
    Emil!

Reviewed-by: Matt Turner <mattst88@gmail.com> (v1)
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
f93533d118 dri: Pass in the dlsym()ed driver extension to screen creation.
This will allow a megadrivers build to reference the actual driver being
loaded from the shared dri_util screen creation code.

v2: Fix indentation, fallback case in EGL (review by Emil).

Reviewed-by: Matt Turner <mattst88@gmail.com> (v1)
Reviewed-by: Chad Versace <chad.versace@linux.intel.com> (v1)
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
67caf36489 gbm: Add support for the new __driDriverGetExtensions interface.
v2: Fix uninitialized variable use in the old-ABI case.

Reviewed-by: Chad Versace <chad.versace@linux.intel.com> (v1)
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
a64bb7553a egl: Add an optional function call for getting the DRI driver interface.
v2: Fix asprintf error checking.

Reviewed-by: Matt Turner <mattst88@gmail.com> (v1)
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
fcb57a8210 glx: Add an optional function call for getting the DRI driver interface.
The previous interface relied on a static struct, which meant that the
driver didn't get a chance to edit the struct before the struct got used.
For megadrivers, I want struct specific to the driver being loaded.

v2: Fix the prototype in the docs (caught by Marek).  Since the driver
    name was in the function, we didn't need to also pass it in.
v3: Fix asprintf error checking (caught by Matt's gcc).

Reviewed-by: Matt Turner <mattst88@gmail.com> (v1)
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
6868923702 dri: Move driver config options to dri driver extensions.
This way they aren't all sitting in the global namespace (with the same
name per driver).

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
cf5d8fc310 dri: Allow config options to be passed to the loader through extensions.
Turns out already we have this nice mechanism for providing optional
things from the driver to the loader, and I was going to have to rename
the public global symbol to avoid conflicts when doing megadrivers.

While the former __driConfigOptions is technically loader interface, this
is the only loader that made use of that symbol.  Continue paying
attention to it if we can't find the new option, to retain compatibility
with old drivers.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Eric Anholt
80806c98ef glx: Move the driver extension-loading to a helper function.
I'm planning on doing driver extension parsing from 3 places, and making
the extension loading step a bit longer.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-24 14:04:20 -07:00
Francisco Jerez
7463abd37d clover: Query maximum kernel block size from the device instead of the kernel object.
Based on a similar fix from Aaron Watry.  It seems unlikely that we
will ever need a kernel-specific setting for this, and the Gallium API
doesn't support it.  Remove kernel::max_block_size() altogether.
2013-10-24 13:33:41 -07:00
Brian Paul
b8d7a97fad glsl: silence unused 'var' variable warning
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-24 10:45:47 -06:00
Brian Paul
8d7b913e4e svga: remove user-space vertex/index buffer code
The gallium vbuf module, which we've been using for some time now, takes
care of uploading user-space vertex/index data into real buffers.  The
upload code in the svga driver was unused.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
2013-10-24 10:45:47 -06:00
Chad Versace
2f6a315085 i965: Print more debuginfo in intel_texsubimage_memcpy()
Print info about packing, format, type, and tiling. This will help debug
future issues with this fastpath.

Reviewed-by: Frank Henigman <fjhenigman@google.com>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2013-10-24 09:25:45 -07:00
Chad Versace
c4205590e7 i965: Fix glTexImage when packing alignment != cpp
Fixes texture corruption of Weston clients on cairo-glesv2 backend.
Commit 49ed599 introduced the bug.

Corruption occured when glTexSubImage called
intel_texsubimage_tiled_memcpy() with:
  x,y=10,9
  w,h=7,7
  format=GL_ALPHA(0x1906)
  type=GL_UNSIGNED_BYTE(0x1401)
  gl_format=MESA_FORMAT_A8(0x18)
  packing.alignemnt=4

The function miscalculated the source image's stride as w*cpp=7 without
taking into account the packing alignment. The actual stride was 8.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70435
Reported-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
Tested-by: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by:Frank Henigman <fjhenigman@google.com>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2013-10-24 09:25:24 -07:00
Rob Clark
a6e45b6a17 freedreno: fix compile error
Small typo introduced in a3ed98f.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
2013-10-23 18:38:05 -06:00
Paul Berry
4df56177ed i965/fs: Only unroll high-accuracy dFdy() from SIMD16 to SIMD8 on gen4 and IVB.
In commit 800610f (i965/fs: Improve accuracy of dFdy() to match
dFdx()) I unrolled the high-accuracy dFdy() computation from a single
SIMD16 instruction to two SIMD8 instructions because of text I found
in the i965 (gen4) PRM saying that instruction compression could not
be used in align16 mode.  I couldn't find similar text in later
hardware docs, and I observed problems trying to use instruction
compression on align16 mode on Ivy Bridge, so I assumed that the
restriction still applied and the associated documentation had simply
been lost.

After consultation with the hardware engineers, it turns out this is
not the case.  In point of fact, the restriction was dropped in gen5,
re-introduced in Ivy Bridge, and dropped again in Haswell.  The reason
I didn't notice this is that in the Ivy Bridge documentation, the
restriction was in a different section, and described using different
language.

Now that we know that the restriction only applies to Gen4 and Ivy
Bridge, we can limit the unrolling to those platforms.

Tested on gen5, gen6, and gen7 (both Ivy Bridge and Haswell).

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-23 16:51:15 -07:00
Paul Berry
8e15207c9d glsl/gs: Prevent illegal input/output primitive types.
From the GLSL 1.50 spec, section 4.3.8.1 (Input Layout Qualifiers):

    The layout qualifier identifiers for geometry shader inputs are

        layout-qualifier-id
            points
            lines
            lines_adjacency
            triangles
            triangles_adjacency

And from section 4.3.8.2 (Output Layout Qualifiers)

    The layout qualifier identifiers for geometry shader outputs are

        layout-qualifier-id
            points
            line_strip
            triangle_strip
            max_vertices = integer-constant

We were erroneously allowing line_strip and triangle_strip to be used
as input qualifiers, and we were allowing lines, lines_adjacency,
triangles, and triangles_adjacency to be used as output qualifiers.

Fixes piglit tests "glsl-1.50-gs-{input,output}-layout-qualifiers *".

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-10-23 16:51:05 -07:00
Eric Anholt
867d0cc1fe i965: Add perf debug hint when the app makes us do index buffer scanning.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:33:46 -07:00
Eric Anholt
c298f5ff56 i965: Try to avoid stalls on the GPU when doing glBufferSubData().
On DOTA2, framerate on dota2-de1.dem in windowed mode on my laptop
improves by 7.69854% +/- 0.909163% (n=3).  In a microbenchmark hitting
this code path (wall time of piglit vbo-subdata-many), runtime decreases
from 0.8 to 0.05 seconds.

v2: Use out of range start/end instead of separate bool for the active
    flag (suggestion by Jordan), fix double-upload in the stalling path.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:33:19 -07:00
Eric Anholt
3b58e0ed64 i965: Be sure to reset brw->vb.buffers[] when trying to redo vertex setup.
The brw_prepare_vertices that sets up buffers[] depends on these
parameters, so don't let brw_prepare_vertices() skip it.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:33:16 -07:00
Eric Anholt
a5e2e7f9a4 i965: Add support for GL_ARB_texture_buffer_range.
Supporting this extension turns out to simplify our code a bit over not
supporting this extension, once the glBufferSubData() synchronization code
lands.

v2: Use 16 byte alignment like we do for uniform buffers, due to unaligned
    access penalties.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> (v1)
2013-10-23 15:33:10 -07:00
Eric Anholt
b37f7e0160 i965: Add a note about the late-allocation in intel_bufferobj_buffer().
This was mostly for the i915 system-memory VBO code, which we don't have
any more, but since that existed we've ended up producing dependencies on
it being there.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:33:06 -07:00
Eric Anholt
060a49a896 i965: Drop intel_bufferobj_source().
Since src_offset was always 0, it wasn't doing anything for us beyond
intel_bufferobj_buffer().

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:33:03 -07:00
Eric Anholt
c0a9436d19 i965: Fix texture buffer rendering after a whole buffer replacement.
If glBufferData(), glBufferSubData(0, obj->Size), or similar happens, we
get a new drm_intel_bo for the buffer object, and thus need to re-upload
texture buffer state so we point at the new data.

Fixes the new piglit GL_ARB_texture_buffer_object/data-sync

Cc: "9.2" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-23 15:31:44 -07:00
David Heidelberger
2901e2efcd clover: fix build after a3ed98f7aa 2013-10-23 13:13:36 -07:00
Brian Paul
c1345720c8 nv50: clamp PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS to PIPE_MAX_SAMPLERS
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70212
Tested-by: Aaron Watry <awatry@gmail.com>
2013-10-23 13:43:18 -06:00
Brian Paul
ef98e2ee61 radeonsi: remove unused si_set_cs_sampler_view()
Fixes build breakage.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70804

Tested-by: Vinson Lee <vlee@freedesktop.org>
2013-10-23 13:42:51 -06:00
Brian Paul
a3ed98f7aa gallium: new, unified pipe_context::set_sampler_views() function
The new function replaces four old functions: set_fragment/vertex/
geometry/compute_sampler_views().

Note: at this time, it's expected that the 'start' parameter will
always be zero.

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Tested-by: Emil Velikov <emil.l.velikov@gmail.com>
2013-10-23 10:15:38 -06:00
Brian Paul
b11fc226e6 svga: remove unneeded include of u_double_list.h 2013-10-23 10:15:38 -06:00
Kenneth Graunke
30bb170479 i965: Expose write_reg() as brw_store_register_mem64().
Writing a 64-bit register value to memory is sufficiently complicated
that it makes sense to reuse this function rather than duplicating it.

Exposing it outside of gen6_queryobj.c means it needs a more descriptive
function name.  It could probably be moved to brw_util.c or somewhere
else, but this works too.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-23 01:06:26 -07:00
Kenneth Graunke
d5db3ece0a i965: Move flushing out of write_reg and into the callers.
The current callers just want to write a single register, so combining
the register read with a pipeline flush made sense.  However, in the
future we'll want to do multiple register reads back to back, and we'll
only want to flush once.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-23 01:06:26 -07:00
Ian Romanick
63974c0f5b glsl: Simplify the interface to link_invalidate_variable_locations
The unit tests added in the previous commits prove some things about the
state of some internal data structures.  The most important of these is
that all built-in input and output variables have explicit_location
set.  This means that link_invalidate_variable_locations doesn't need to
know the range of non-generic shader inputs or outputs.  It can simply
reset location state depending on whether explicit_location is set.

There are two additional assumptions that were already implicit in the
code that comments now document.

  - ir_variable::is_unmatched_generic_inout is only used by the linker
    when connecting outputs from one shader stage to inputs of another
    shader stage.

  - Any varying that has explicit_location set must be a built-in.  This
    will be true until GL_ARB_separate_shader_objects is supported.

As a result, the input_base and output_base parameters to
link_invalidate_variable_locations are no longer necessary, and the code
for resetting locations and setting is_unmatched_generic_inout can be
simplified.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
1eee0a9f01 glsl/tests: Unit test vertex shader in / out with link_invalidate_variable_locations
Validates:

  - ir_variable::explicit_location should not be modified.

  - If ir_variable::explicit_location is not set, ir_variable::location,
    ir_variable::location_frac, and
    ir_variable::is_unmatched_generic_inout must be reset to 0.

  - If ir_variable::explicit_location is set, ir_variable::location
    should not be modified.  ir_variable::location_frac, and
    ir_variable::is_unmatched_generic_inout must be reset to 0.
    Previous unit tests have shown that all non-generic inputs / outputs
    have explicit_location set.

v2: Split the link_invalidate_variable_locations interface change out to
a separate patch.  Remove the vertex_in_builtin_without_explicit and
vertex_out_builtin_without_explicit tests.  There was a lot of good
discussion about this on the mailing list to which I refer the
interested reader.  Both changes suggested by Paul.

    http://lists.freedesktop.org/archives/mesa-dev/2013-October/046652.html

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
cf8b14ce6d glsl: Modify interface to link_invalidate_variable_locations
This will make it easier to unit test this function in successive
patches.  Also, correct the prototype in linker.h.  It was... wrong.

v2: Split the interface change from adding the unit tests.  Suggested by
Paul.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
af229c94e3 glsl/tests: Verify geometry shader built-ins generated by _mesa_glsl_initialize_variables
Checks that the variables generated meet certain criteria.

 - Geometry shader inputs have an explicit location.

 - Geometry shader outputs have an explicit location.

 - Fragment shader-only varying locations are not used.

 - Geometry shader uniforms and system values don't have an explicit
   location.

 - Geometry shader constants don't have an explicit location and are
   read-only.

 - No other kinds of geometry variables exist.

It does not verify that an specific variables exist.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
f094a0f825 glsl/tests: Verify fragment shader built-ins generated by _mesa_glsl_initialize_variables
Checks that the variables generated meet certain criteria.

 - Fragment shader inputs have an explicit location.

 - Fragment shader outputs have an explicit location.

 - Vertex / geometry shader-only varying locations are not used.

 - Fragment shader uniforms and system values don't have an explicit
   location.

 - Fragment shader constants don't have an explicit location and are
   read-only.

 - No other kinds of fragment variables exist.

It does not verify that an specific variables exist.

v2: Use _mesa_varying_slot_in_fs in
fragment_builtin.inputs_have_explicit_location.  Suggested by Paul.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
d05202900b glsl/tests: Verify vertex shader built-ins generated by _mesa_glsl_initialize_variables
Checks that the variables generated meet certain criteria.

 - Vertex shader inputs have an explicit location.

 - Vertex shader outputs have an explicit location.

 - Fragment shader-only varying locations are not used.

 - Vertex shader uniforms and system values don't have an explicit
   location.

 - Vertex shader constants don't have an explicit location and are
   read-only.

 - No other kinds of vertex variables exist.

It does not verify that an specific variables exist.

v2: Fix memory management mistakes in
common_builtin::string_starts_with_prefix.  Clean up error message
reporting in common_builtin::no_invalid_variable_modes.  Both suggested
by Paul.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
78b70ceae1 glsl: When constructing a variable with an interface type, set interface_type
Ever since the addition of interface blocks with instance names, we have
had an implicit invariant:

    var->type->is_interface() ==
        (var->type == var->interface_type)

The odd use of == here is intentional because !var->type->is_interface()
implies var->type != var->interface_type.

Further, if var->type->is_array() is true, we have a related implicit
invariant:

    var->type->fields.array->is_interface() ==
        (var->type->fields.array == var->interface_type)

However, the ir_variable constructor doesn't maintain either invariant.
That seems kind of silly... and I tripped over it while writing some
other code.  This patch makes the constructor do the right thing, and it
introduces some tests to verify that behavior.

v2: Add general-ir-test to .gitignore.  Update the description of the
ir_variable invariant for arrays in the commit message.  Both suggested
by Paul.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-10-22 15:23:30 -07:00
Ian Romanick
09ceed7587 mesa/tests: Add simple, dumb test for _mesa_program_state_string
After some discussions about the correct way to update
_mesa_program_state_string, I decided to make a unit test for the
function.  It turns out that the function didn't work quite the way I
thought.  The unit test proves that the code was already correct.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Cc: Anuj Phogat <anuj.phogat@gmail.com>
2013-10-22 15:23:30 -07:00
Ander Conselvan de Oliveira
98b359bd1b wayland: Don't leak wl_drm global when unbinding display 2013-10-22 14:57:03 -07:00
Scott Graham
dafa97fed9 mesa: fixes for MSVC 2013
Cc: "9.2" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
2013-10-22 08:39:40 -06:00
Brian Paul
65ee044a97 st/mesa: minor whitespace, comment changes in st_draw.c 2013-10-22 08:20:45 -06:00
Brian Paul
f166fbae36 st/dri: minor formatting clean-ups in dri_context.c 2013-10-22 08:20:45 -06:00
Brian Paul
f0d4636d9c mesa: fix a couple issues with U_FIXED, I_FIXED macros
Silence a bunch of MSVC type conversion warnings.

Changed return type of S_FIXED to int32_t (signed).  The result
is the same.  It just seems more intuitive that a signed conversion
function should return a signed value.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
2013-10-22 08:20:45 -06:00
Brian Paul
6767c56e6d mesa: remove GL_MESA_program_debug bits from gl.h
The code for this was removed from Mesa some time ago.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-10-22 08:20:45 -06:00
Brian Paul
971c74309e mesa: remove remnants of GL_MESA_shader_debug
This extension never saw any real use so remove it.

v2: also update tests/num_strings.cpp for 'make check'

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-10-22 08:20:45 -06:00
Kenneth Graunke
43b05b8fac i965: Only emit interpolation setup if there are actual FS inputs.
Dead code elimination would get rid of the extra instructions, but
skipping this saves iterations through the optimization loop.

From shader-db:

      N     Min     Max        Median           Avg        Stddev
x 14672       3      16             3     3.1334515    0.59904168
+ 14672       1      16             3     2.8955153    0.77732963
Difference at 95.0% confidence
        -0.237936 +/- 0.0158798
        -7.59342% +/- 0.506783%
        (Student's t, pooled s = 0.693935)

Embarassingly, the classic shadow mapping shader:

   void main() { }

used to require three iterations through the optimization loop.
With this patch, it only requires one (which makes no progress).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-21 23:31:15 -07:00
Chris Forbes
c4de86fd26 i965/fs: Fix accidental type conversion in header setup
Previously one side could be UD while the other was float.

V2: Prefer float; apparently IVB can dispatch float ops faster. (Thanks
Eric)

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-22 18:56:14 +13:00
Chris Forbes
b38af01ccf i965/fs: Fix handling of sampler messages with header but zero offset
Gather unconditionally uses a header, but in some cases the
texture_offset value will be zero.

V2: Don't introduce a bogus conversion.

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-22 18:56:14 +13:00
Matt Turner
f1e605f1ad glsl: Optimize -(-expr) into expr.
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-21 22:53:36 -07:00
Matt Turner
963df4d37d glsl: Optimize abs(-expr) and abs(abs(expr)) into abs(expr).
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
2013-10-21 22:53:36 -07:00