⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286796 in webkit


Ignore:
Timestamp:
Dec 9, 2021, 12:25:11 PM (5 years ago)
Author:
Said Abou-Hallawa
Message:

[GPU Process] [Filters] Add the encoding and decoding for LightSource
https://bugs.webkit.org/show_bug.cgi?id=234086

Reviewed by Wenson Hsieh.

This will allow encoding and decoding FEDiffuseLighting and FESpecularLighting.

The create() and the constructor of the LightSource super classes have
to be non-inline to overcome a "missing vtable" linking issue.

New constructors are added to FEDiffuseLighting and FESpecularLighting
to allow creating these super classes from the combined data members of
FELighting.

m_bufferPosition of PointLightSource and SpotLightSource are used to cache
the absolute value of m_userSpacePosition relative to the result FilterImage.
So it does not need to be encoded/decoded since it is initialized by
FELightingSoftwareApplier.

  • Headers.cmake:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/filters/DistantLightSource.cpp:

(WebCore::DistantLightSource::create):
(WebCore::DistantLightSource::DistantLightSource):

  • platform/graphics/filters/DistantLightSource.h:

(WebCore::DistantLightSource::encode const):
(WebCore::DistantLightSource::decode):
(WebCore::DistantLightSource::create): Deleted.
(WebCore::DistantLightSource::DistantLightSource): Deleted.

  • platform/graphics/filters/FEDiffuseLighting.cpp:

(WebCore::FEDiffuseLighting::create):

  • platform/graphics/filters/FEDiffuseLighting.h:
  • platform/graphics/filters/FELighting.h:

(WebCore::FELighting::encode const):
(WebCore::FELighting::decode):

  • platform/graphics/filters/FESpecularLighting.cpp:

(WebCore::FESpecularLighting::create):

  • platform/graphics/filters/FESpecularLighting.h:
  • platform/graphics/filters/LightSource.h:
  • platform/graphics/filters/PointLightSource.cpp:

(WebCore::PointLightSource::create):
(WebCore::PointLightSource::PointLightSource):

  • platform/graphics/filters/PointLightSource.h:

(WebCore::PointLightSource::encode const):
(WebCore::PointLightSource::decode):
(WebCore::PointLightSource::create): Deleted.
(WebCore::PointLightSource::PointLightSource): Deleted.

  • platform/graphics/filters/SpotLightSource.cpp:

(WebCore::SpotLightSource::create):
(WebCore::SpotLightSource::SpotLightSource):

  • platform/graphics/filters/SpotLightSource.h:

(WebCore::SpotLightSource::encode const):
(WebCore::SpotLightSource::decode):
(WebCore::SpotLightSource::create): Deleted.
(WebCore::SpotLightSource::SpotLightSource): Deleted.

Location:
trunk/Source/WebCore
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286795 r286796  
     12021-12-09  Said Abou-Hallawa  <said@apple.com>
     2
     3        [GPU Process] [Filters] Add the encoding and decoding for LightSource
     4        https://bugs.webkit.org/show_bug.cgi?id=234086
     5
     6        Reviewed by Wenson Hsieh.
     7
     8        This will allow encoding and decoding FEDiffuseLighting and FESpecularLighting.
     9
     10        The create() and the constructor of the LightSource super classes have
     11        to be non-inline to overcome a "missing vtable" linking issue.
     12
     13        New constructors are added to FEDiffuseLighting and FESpecularLighting
     14        to allow creating these super classes from the combined data members of
     15        FELighting.
     16
     17        m_bufferPosition of PointLightSource and SpotLightSource are used to cache
     18        the absolute value of m_userSpacePosition relative to the result FilterImage.
     19        So it does not need to be encoded/decoded since it is initialized by
     20        FELightingSoftwareApplier.
     21
     22        * Headers.cmake:
     23        * WebCore.xcodeproj/project.pbxproj:
     24        * platform/graphics/filters/DistantLightSource.cpp:
     25        (WebCore::DistantLightSource::create):
     26        (WebCore::DistantLightSource::DistantLightSource):
     27        * platform/graphics/filters/DistantLightSource.h:
     28        (WebCore::DistantLightSource::encode const):
     29        (WebCore::DistantLightSource::decode):
     30        (WebCore::DistantLightSource::create): Deleted.
     31        (WebCore::DistantLightSource::DistantLightSource): Deleted.
     32        * platform/graphics/filters/FEDiffuseLighting.cpp:
     33        (WebCore::FEDiffuseLighting::create):
     34        * platform/graphics/filters/FEDiffuseLighting.h:
     35        * platform/graphics/filters/FELighting.h:
     36        (WebCore::FELighting::encode const):
     37        (WebCore::FELighting::decode):
     38        * platform/graphics/filters/FESpecularLighting.cpp:
     39        (WebCore::FESpecularLighting::create):
     40        * platform/graphics/filters/FESpecularLighting.h:
     41        * platform/graphics/filters/LightSource.h:
     42        * platform/graphics/filters/PointLightSource.cpp:
     43        (WebCore::PointLightSource::create):
     44        (WebCore::PointLightSource::PointLightSource):
     45        * platform/graphics/filters/PointLightSource.h:
     46        (WebCore::PointLightSource::encode const):
     47        (WebCore::PointLightSource::decode):
     48        (WebCore::PointLightSource::create): Deleted.
     49        (WebCore::PointLightSource::PointLightSource): Deleted.
     50        * platform/graphics/filters/SpotLightSource.cpp:
     51        (WebCore::SpotLightSource::create):
     52        (WebCore::SpotLightSource::SpotLightSource):
     53        * platform/graphics/filters/SpotLightSource.h:
     54        (WebCore::SpotLightSource::encode const):
     55        (WebCore::SpotLightSource::decode):
     56        (WebCore::SpotLightSource::create): Deleted.
     57        (WebCore::SpotLightSource::SpotLightSource): Deleted.
     58
    1592021-12-09  Matt Woodrow  <matt.woodrow@gmail.com>
    260
  • trunk/Source/WebCore/Headers.cmake

    r286772 r286796  
    15751575    platform/graphics/cv/ImageTransferSessionVT.h
    15761576
     1577    platform/graphics/filters/DistantLightSource.h
    15771578    platform/graphics/filters/FEBlend.h
    15781579    platform/graphics/filters/FEColorMatrix.h
     
    16021603    platform/graphics/filters/FilterOperations.h
    16031604    platform/graphics/filters/LightSource.h
     1605    platform/graphics/filters/PointLightSource.h
    16041606    platform/graphics/filters/SourceAlpha.h
    16051607    platform/graphics/filters/SourceGraphic.h
     1608    platform/graphics/filters/SpotLightSource.h
    16061609
    16071610    platform/graphics/iso/ISOBox.h
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r286772 r286796  
    27302730                845E72FC0FD2623900A87D79 /* SVGFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 845E72FA0FD2623900A87D79 /* SVGFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27312731                84650E7E2387AD7D006266E2 /* MediaQueryListEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84650E7C2387AD7C006266E2 /* MediaQueryListEvent.h */; };
    2732                 84730D771248F0B300D3A9C9 /* DistantLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D5A1248F0B300D3A9C9 /* DistantLightSource.h */; };
     2732                84730D771248F0B300D3A9C9 /* DistantLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D5A1248F0B300D3A9C9 /* DistantLightSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27332733                84730D791248F0B300D3A9C9 /* FEConvolveMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D5C1248F0B300D3A9C9 /* FEConvolveMatrix.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27342734                84730D7B1248F0B300D3A9C9 /* FEDiffuseLighting.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D5E1248F0B300D3A9C9 /* FEDiffuseLighting.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    27432743                84730D8D1248F0B300D3A9C9 /* FETurbulence.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D701248F0B300D3A9C9 /* FETurbulence.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27442744                84730D911248F0B300D3A9C9 /* LightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D741248F0B300D3A9C9 /* LightSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
    2745                 84730D921248F0B300D3A9C9 /* PointLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D751248F0B300D3A9C9 /* PointLightSource.h */; };
    2746                 84730D931248F0B300D3A9C9 /* SpotLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D761248F0B300D3A9C9 /* SpotLightSource.h */; };
     2745                84730D921248F0B300D3A9C9 /* PointLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D751248F0B300D3A9C9 /* PointLightSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2746                84730D931248F0B300D3A9C9 /* SpotLightSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84730D761248F0B300D3A9C9 /* SpotLightSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
    27472747                8476C9E611DF6A0B00555B02 /* SVGPathSegListBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8476C9E411DF6A0B00555B02 /* SVGPathSegListBuilder.h */; };
    27482748                8476C9EB11DF6A2900555B02 /* SVGPathBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8476C9E811DF6A2900555B02 /* SVGPathBuilder.h */; };
  • trunk/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp

    r286287 r286796  
    3535
    3636namespace WebCore {
     37
     38Ref<DistantLightSource> DistantLightSource::create(float azimuth, float elevation)
     39{
     40    return adoptRef(*new DistantLightSource(azimuth, elevation));
     41}
     42
     43DistantLightSource::DistantLightSource(float azimuth, float elevation)
     44    : LightSource(LS_DISTANT)
     45    , m_azimuth(azimuth)
     46    , m_elevation(elevation)
     47{
     48}
    3749
    3850void DistantLightSource::initPaintingData(const Filter&, const FilterImage&, PaintingData& paintingData) const
  • trunk/Source/WebCore/platform/graphics/filters/DistantLightSource.h

    r286287 r286796  
    3030class DistantLightSource : public LightSource {
    3131public:
    32     static Ref<DistantLightSource> create(float azimuth, float elevation)
    33     {
    34         return adoptRef(*new DistantLightSource(azimuth, elevation));
    35     }
     32    WEBCORE_EXPORT static Ref<DistantLightSource> create(float azimuth, float elevation);
    3633
    3734    // These are in degrees.
     
    4744    WTF::TextStream& externalRepresentation(WTF::TextStream&) const override;
    4845
     46    template<class Encoder> void encode(Encoder&) const;
     47    template<class Decoder> static std::optional<Ref<DistantLightSource>> decode(Decoder&);
     48
    4949private:
    50     DistantLightSource(float azimuth, float elevation)
    51         : LightSource(LS_DISTANT)
    52         , m_azimuth(azimuth)
    53         , m_elevation(elevation)
    54     {
    55     }
     50    DistantLightSource(float azimuth, float elevation);
    5651
    5752    float m_azimuth;
     
    5954};
    6055
     56template<class Encoder>
     57void DistantLightSource::encode(Encoder& encoder) const
     58{
     59    encoder << m_azimuth;
     60    encoder << m_elevation;
     61}
     62
     63template<class Decoder>
     64std::optional<Ref<DistantLightSource>> DistantLightSource::decode(Decoder& decoder)
     65{
     66    std::optional<float> azimuth;
     67    decoder >> azimuth;
     68    if (!azimuth)
     69        return std::nullopt;
     70
     71    std::optional<float> elevation;
     72    decoder >> elevation;
     73    if (!elevation)
     74        return std::nullopt;
     75
     76    return DistantLightSource::create(*azimuth, *elevation);
     77}
     78
    6179} // namespace WebCore
    6280
  • trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp

    r286589 r286796  
    2929
    3030namespace WebCore {
     31
     32Ref<FEDiffuseLighting> FEDiffuseLighting::create(const Color& lightingColor, float surfaceScale, float diffuseConstant, float, float, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&& lightSource)
     33{
     34    return create(lightingColor, surfaceScale, diffuseConstant, kernelUnitLengthX, kernelUnitLengthY, WTFMove(lightSource));
     35}
    3136
    3237Ref<FEDiffuseLighting> FEDiffuseLighting::create(const Color& lightingColor, float surfaceScale, float diffuseConstant, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&& lightSource)
  • trunk/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h

    r286589 r286796  
    3131class FEDiffuseLighting : public FELighting {
    3232public:
     33    WEBCORE_EXPORT static Ref<FEDiffuseLighting> create(const Color& lightingColor, float surfaceScale, float diffuseConstant, float, float, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&&);
    3334    static Ref<FEDiffuseLighting> create(const Color& lightingColor, float surfaceScale, float diffuseConstant, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&&);
    3435
  • trunk/Source/WebCore/platform/graphics/filters/FELighting.h

    r286538 r286796  
    2929
    3030#include "Color.h"
     31#include "DistantLightSource.h"
    3132#include "FilterEffect.h"
    32 #include "LightSource.h"
     33#include "PointLightSource.h"
     34#include "SpotLightSource.h"
    3335
    3436namespace WebCore {
     
    9193    encoder << m_kernelUnitLengthX;
    9294    encoder << m_kernelUnitLengthY;
    93     // FIXME: encode m_lightSource.
     95   
     96    encoder << m_lightSource->type();
     97    switch (m_lightSource->type()) {
     98    case LS_DISTANT:
     99        downcast<DistantLightSource>(m_lightSource.get()).encode(encoder);
     100        break;
     101    case LS_POINT:
     102        downcast<PointLightSource>(m_lightSource.get()).encode(encoder);
     103        break;
     104    case LS_SPOT:
     105        downcast<SpotLightSource>(m_lightSource.get()).encode(encoder);
     106        break;
     107    }
    94108}
    95109
     
    132146        return std::nullopt;
    133147
    134     // FIXME: decode m_lightSource.
    135     return std::nullopt;
     148    std::optional<LightType> lightSourceType;
     149    decoder >> lightSourceType;
     150    if (!lightSourceType)
     151        return std::nullopt;
     152
     153    std::optional<Ref<LightSource>> lightSource;
     154    switch (*lightSourceType) {
     155    case LS_DISTANT:
     156        lightSource = DistantLightSource::decode(decoder);
     157        break;
     158    case LS_POINT:
     159        lightSource = PointLightSource::decode(decoder);
     160        break;
     161    case LS_SPOT:
     162        lightSource = SpotLightSource::decode(decoder);
     163        break;
     164    }
     165
     166    if (!lightSource)
     167        return std::nullopt;
     168
     169    return ClassName::create(*lightingColor, *surfaceScale, *diffuseConstant, *specularConstant, *specularExponent, *kernelUnitLengthX, *kernelUnitLengthY, WTFMove(*lightSource));
    136170}
    137171
  • trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp

    r286589 r286796  
    2929
    3030namespace WebCore {
     31
     32Ref<FESpecularLighting> FESpecularLighting::create(const Color& lightingColor, float surfaceScale, float, float specularConstant, float specularExponent, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&& lightSource)
     33{
     34    return create(lightingColor, surfaceScale, specularConstant, specularExponent, kernelUnitLengthX, kernelUnitLengthY, WTFMove(lightSource));
     35}
    3136
    3237Ref<FESpecularLighting> FESpecularLighting::create(const Color& lightingColor, float surfaceScale, float specularConstant, float specularExponent, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&& lightSource)
  • trunk/Source/WebCore/platform/graphics/filters/FESpecularLighting.h

    r286589 r286796  
    2929class FESpecularLighting : public FELighting {
    3030public:
     31    WEBCORE_EXPORT static Ref<FESpecularLighting> create(const Color& lightingColor, float surfaceScale, float, float specularConstant, float specularExponent, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&&);
    3132    static Ref<FESpecularLighting> create(const Color& lightingColor, float surfaceScale, float specularConstant, float specularExponent, float kernelUnitLengthX, float kernelUnitLengthY, Ref<LightSource>&&);
    3233
  • trunk/Source/WebCore/platform/graphics/filters/LightSource.h

    r286287 r286796  
    9494} // namespace WebCore
    9595
     96namespace WTF {
     97
     98template<> struct EnumTraits<WebCore::LightType> {
     99    using values = EnumValues<
     100        WebCore::LightType,
     101
     102        WebCore::LS_DISTANT,
     103        WebCore::LS_POINT,
     104        WebCore::LS_SPOT
     105    >;
     106};
     107
     108} // namespace WTF
     109
    96110#define SPECIALIZE_TYPE_TRAITS_LIGHTSOURCE(ClassName, Type) \
    97111SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ClassName) \
  • trunk/Source/WebCore/platform/graphics/filters/PointLightSource.cpp

    r286287 r286796  
    3838
    3939namespace WebCore {
     40
     41Ref<PointLightSource> PointLightSource::create(const FloatPoint3D& position)
     42{
     43    return adoptRef(*new PointLightSource(position));
     44}
     45
     46PointLightSource::PointLightSource(const FloatPoint3D& position)
     47    : LightSource(LS_POINT)
     48    , m_userSpacePosition(position)
     49{
     50}
    4051
    4152void PointLightSource::initPaintingData(const Filter& filter, const FilterImage& result, PaintingData&) const
  • trunk/Source/WebCore/platform/graphics/filters/PointLightSource.h

    r286287 r286796  
    3131class PointLightSource : public LightSource {
    3232public:
    33     static Ref<PointLightSource> create(const FloatPoint3D& position)
    34     {
    35         return adoptRef(*new PointLightSource(position));
    36     }
     33    WEBCORE_EXPORT static Ref<PointLightSource> create(const FloatPoint3D& position);
    3734
    3835    const FloatPoint3D& position() const { return m_userSpacePosition; }
     
    4643    WTF::TextStream& externalRepresentation(WTF::TextStream&) const override;
    4744
     45    template<class Encoder> void encode(Encoder&) const;
     46    template<class Decoder> static std::optional<Ref<PointLightSource>> decode(Decoder&);
     47
    4848private:
    49     PointLightSource(const FloatPoint3D& position)
    50         : LightSource(LS_POINT)
    51         , m_userSpacePosition(position)
    52     {
    53     }
     49    PointLightSource(const FloatPoint3D& position);
    5450
    5551    FloatPoint3D m_userSpacePosition;
     
    5753};
    5854
     55template<class Encoder>
     56void PointLightSource::encode(Encoder& encoder) const
     57{
     58    encoder << m_userSpacePosition;
     59}
     60
     61template<class Decoder>
     62std::optional<Ref<PointLightSource>> PointLightSource::decode(Decoder& decoder)
     63{
     64    std::optional<FloatPoint3D> userSpacePosition;
     65    decoder >> userSpacePosition;
     66    if (!userSpacePosition)
     67        return std::nullopt;
     68
     69    return PointLightSource::create(*userSpacePosition);
     70}
     71
    5972} // namespace WebCore
    6073
  • trunk/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp

    r286287 r286796  
    4444static const float antialiasThreshold = 0.016f;
    4545
     46Ref<SpotLightSource> SpotLightSource::create(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
     47{
     48    return adoptRef(*new SpotLightSource(position, direction, specularExponent, limitingConeAngle));
     49}
     50
     51SpotLightSource::SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
     52    : LightSource(LS_SPOT)
     53    , m_userSpacePosition(position)
     54    , m_userSpacePointsAt(direction)
     55    , m_specularExponent(specularExponent)
     56    , m_limitingConeAngle(limitingConeAngle)
     57{
     58}
     59
    4660void SpotLightSource::initPaintingData(const Filter& filter, const FilterImage& result, PaintingData& paintingData) const
    4761{
  • trunk/Source/WebCore/platform/graphics/filters/SpotLightSource.h

    r286287 r286796  
    3131class SpotLightSource : public LightSource {
    3232public:
    33     static Ref<SpotLightSource> create(const FloatPoint3D& position,
    34         const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
    35     {
    36         return adoptRef(*new SpotLightSource(position, direction, specularExponent, limitingConeAngle));
    37     }
     33    WEBCORE_EXPORT static Ref<SpotLightSource> create(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle);
    3834
    3935    const FloatPoint3D& position() const { return m_userSpacePosition; }
     
    5753    WTF::TextStream& externalRepresentation(WTF::TextStream&) const override;
    5854
     55    template<class Encoder> void encode(Encoder&) const;
     56    template<class Decoder> static std::optional<Ref<SpotLightSource>> decode(Decoder&);
     57
    5958private:
    60     SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
    61         : LightSource(LS_SPOT)
    62         , m_userSpacePosition(position)
    63         , m_userSpacePointsAt(direction)
    64         , m_specularExponent(specularExponent)
    65         , m_limitingConeAngle(limitingConeAngle)
    66     {
    67     }
     59    SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle);
    6860
    6961    FloatPoint3D m_userSpacePosition;
     
    7668};
    7769
     70template<class Encoder>
     71void SpotLightSource::encode(Encoder& encoder) const
     72{
     73    encoder << m_userSpacePosition;
     74    encoder << m_userSpacePointsAt;
     75    encoder << m_specularExponent;
     76    encoder << m_limitingConeAngle;
     77}
     78
     79template<class Decoder>
     80std::optional<Ref<SpotLightSource>> SpotLightSource::decode(Decoder& decoder)
     81{
     82    std::optional<FloatPoint3D> userSpacePosition;
     83    decoder >> userSpacePosition;
     84    if (!userSpacePosition)
     85        return std::nullopt;
     86
     87    std::optional<FloatPoint3D> userSpacePointsAt;
     88    decoder >> userSpacePointsAt;
     89    if (!userSpacePointsAt)
     90        return std::nullopt;
     91
     92    std::optional<float> specularExponent;
     93    decoder >> specularExponent;
     94    if (!specularExponent)
     95        return std::nullopt;
     96
     97    std::optional<float> limitingConeAngle;
     98    decoder >> limitingConeAngle;
     99    if (!limitingConeAngle)
     100        return std::nullopt;
     101
     102    return SpotLightSource::create(*userSpacePosition, *userSpacePointsAt, *specularExponent, *limitingConeAngle);
     103}
     104
    78105} // namespace WebCore
    79106
Note: See TracChangeset for help on using the changeset viewer.