hostsupport/hostopenvg/src/riPixelPipe.h
author Matt Plumtree <matt.plumtree@nokia.com>
Wed, 06 Oct 2010 17:59:01 +0100
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 24 holdingarea/vg/2D_OpenVG_1_1_SF/ri/src/riPixelPipe.h@a3f46bb01be2
permissions -rw-r--r--
Copy code from the holdingarea into the target locations. Some initial rework of CMakeLists.txt files, but not yet tested.

#ifndef __RIPIXELPIPE_H
#define __RIPIXELPIPE_H

/*------------------------------------------------------------------------
 *
 * OpenVG 1.1 Reference Implementation
 * -----------------------------------
 *
 * Copyright (c) 2007 The Khronos Group Inc.
 * Portions copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and /or associated documentation files
 * (the "Materials "), to deal in the Materials without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Materials,
 * and to permit persons to whom the Materials are furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Materials.
 *
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
 * THE USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 *//**
 * \file
 * \brief	Paint and PixelPipe classes.
 * \note
 *//*-------------------------------------------------------------------*/

#ifndef __RIMATH_H
#include "riMath.h"
#endif

#ifndef __RIIMAGE_H
#include "riImage.h"
#endif

//=======================================================================

namespace OpenVGRI
{

struct Span;
class PPCompiler;
class PixelPipe;

/*-------------------------------------------------------------------*//*!
* \brief	Storage and operations for VGPaint.
* \param
* \return
* \note
*//*-------------------------------------------------------------------*/

class Paint
{
public:
    enum { GRADIENT_LUT_BITS = 8 };
    enum { GRADIENT_LUT_COUNT = 1 << GRADIENT_LUT_BITS };
    enum { GRADIENT_LUT_MASK = (1<<GRADIENT_LUT_BITS)-1 };

    struct GradientStop
    {
        GradientStop() : offset(0.0f), color(0.0f, 0.0f, 0.0f, 0.0f, Color::sRGBA) {}
        RIfloat		offset;
        Color		color;
    };

public:
    Paint();
    ~Paint();
    void					addReference()							{ m_referenceCount++; }
    int						removeReference()						{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
    void                    setColor(const Color& color) {m_paintColor = color; m_paintColor.clamp(); m_paintColor.premultiply(); }
    void                    setGradientStops(Array<GradientStop>& inputStops, Array<GradientStop>& stops);
    void                    generateLUT(PixelPipe& pipe, VGImageFormat targetFormat);
    const IntegerColor*     getGradientLUT() const { return m_gradientLUT; }
    void                    setLinearGradient(const Vector2& p0, const Vector2& p1);
    void                    setRadialGradient(const Vector2& c, const Vector2& f, VGfloat r);
    bool                    linearDegenerate() const;
    bool                    radialDegenerate() const;
    Color                   getSolidColor() const;
    
    Color integrateColorRamp(RIfloat gmin, RIfloat gmax) const; // \todo Private after modifications.
    
public:
    VGPaintType				m_paintType;
    Color					m_paintColor;
    Color					m_inputPaintColor;
    VGColorRampSpreadMode	m_colorRampSpreadMode;
    Array<GradientStop>		m_colorRampStops;
    Array<GradientStop>		m_inputColorRampStops;
    VGboolean				m_colorRampPremultiplied;
    Vector2					m_inputLinearGradientPoint0;
    Vector2					m_inputLinearGradientPoint1;
    Vector2					m_inputRadialGradientCenter;
    Vector2					m_inputRadialGradientFocalPoint;
    RIfloat					m_inputRadialGradientRadius;
    Vector2					m_linearGradientPoint0;
    Vector2					m_linearGradientPoint1;
    Vector2					m_radialGradientCenter;
    Vector2					m_radialGradientFocalPoint;
    RIfloat					m_radialGradientRadius;
    VGTilingMode			m_patternTilingMode;
    Image*					m_pattern;
private:
    Paint(const Paint&);						//!< Not allowed.
    const Paint& operator=(const Paint&);		//!< Not allowed.

    int						m_referenceCount;
    IntegerColor            m_gradientLUT[GRADIENT_LUT_COUNT];
    VGImageFormat           m_lutFormat;
    bool                    m_gradientStopsChanged;
    bool                    m_gradientDegenerate;
};

/*-------------------------------------------------------------------*//*!
* \brief	Encapsulates all information needed for painting a pixel.
* \param
* \return
* \note
*//*-------------------------------------------------------------------*/

#define RGRAD_FLOATS
#if defined(RGRAD_FLOATS)
typedef RIfloat RGScalar;
#else
typedef double RGScalar;
#endif

class PixelPipe
{
public:
    enum SamplerType 
    {
        SAMPLER_TYPE_NEAREST    = 0,
        SAMPLER_TYPE_LINEAR     = 1,
        SAMPLER_TYPE_SIZE
    };
    
    enum TilingMode 
    {
        TILING_MODE_PAD         = 0,
        TILING_MODE_REPEAT      = 1,
        TILING_MODE_REFLECT     = 2,
        TILING_MODE_FILL        = 3,
        TILING_MODE_SIZE
    };
    
    // Span per-pixel variants:
    struct PPVariants
    {
        void*       dst;
        void*       src;
        void*       maskPtr;
        int         coverage;

        RIuint32    dstX;

        RIint32     sx;
        RIint32     sy;

        RGScalar    rx;
        RGScalar    ry;

        // \todo Image sampling coordinates will be in fixed point if transform is affine,
        // in floating point if not.
        RGScalar    ix;
        RGScalar    iy;

        RIint32     iImageX;  
        RIint32     iImageY;
        RIfloat     fImageX;
        RIfloat     fImageY;
        RIfloat     fImageW;
    };
    
    // Uniform state per-pixel
    // \todo Organize into sub-structures?
    struct PPUniforms
    {
        // \todo Do not store pointers to classes, only atoms! It should make the
        // dynamic compilation a lot easier.
        void*           srcPtr;
        RIint32         srcStride;
        void*           dstPtr;
        RIint32         dstStride;
        void*           maskPtr;
        int             maskStride;
        void*           imagePtr;
        int             imageStride;
        void*           patternPtr;
        int             patternStride;
        const IntegerColor*   gradientLookup;
        const RIint32*        colorTransformValues;

        // Linear gradient
        RIint32         dgdx;
        RIint32         dgdy;
        RIint32         lgc;

        // Radial gradient
        RGScalar        rsqrp;
        RGScalar        rfxp;
        RGScalar        rfyp;
        RGScalar        rx0;
        RGScalar        ry0;
        RGScalar        rdxdx;
        RGScalar        rdxdy;
        RGScalar        rdydx;
        RGScalar        rdydy;

        // Pattern. Note that pattern and image may be used at the same time.
        RIint32         paint_width;
        RIint32         paint_height;
        RIint32         paint_x0;
        RIint32         paint_y0;
        RIint32         paint_dxdx;
        RIint32         paint_dxdy;
        RIint32         paint_dydx;
        RIint32         paint_dydy;

        // Image
        RIint32         image_iWidth;
        RIint32         image_iHeight;
        RIint32         image_ix0;
        RIint32         image_iy0;
        RIint32         image_idxdx;
        RIint32         image_idxdy;
        RIint32         image_idydx;
        RIint32         image_idydy;


        RIfloat         image_fWidth;
        RIfloat         image_fHeight;
        RIfloat         image_fx0;
        RIfloat         image_fy0;
        RIfloat         image_fw0;
        RIfloat         image_fdxdx;
        RIfloat         image_fdxdy;
        RIfloat         image_fdydx;
        RIfloat         image_fdydy;
        RIfloat         image_fdwdx;
        RIfloat         image_fdwdy;

        IntegerColor    tileFillColor;
        IntegerColor    solidColor;
        RIuint32        packedSolidColor;
    };

    enum ImageGradientType {
        GRADIENT_TYPE_INTEGER   = 0,
        GRADIENT_TYPE_FIXED     = 1,
        GRADIENT_TYPE_FLOAT     = 2,
        GRADIENT_TYPE_SIZE
    };

    // Signature state contains all the information necessary to compile
    // a pixel-pipeline. Note that some of these are actually derived.
    // \note REMEMBER TO UPDATE THE COMPILER. For now, there is now
    // automatic mechanism to propagate changes to that component!
    struct SignatureState
    {
        VGBlendMode         blendMode;
        VGImageMode         imageMode;
        VGPaintType         paintType;
        VGMaskOperation     maskOperation;
        TilingMode          paintTilingMode;
        SamplerType         paintSampler;
        SamplerType         imageSampler;

        ImageGradientType   imageGradientType;

        Color::Descriptor   dstDesc;
        Color::Descriptor   maskDesc;
        Color::Descriptor   imageDesc;
        Color::Descriptor   patternDesc;

        bool                hasMasking;
        bool                hasImage;
        bool                hasColorTransform;
        bool                isRenderToMask;
        bool                fillColorTransparent;
        // When using external data for rendering an image: This is the only case
        // where the data can be invalid in the pixel-pipe.
        bool                unsafeImageInput; 

    };

public:
    PixelPipe();	//throws bad_alloc
    ~PixelPipe();

    void	pixelPipe(int x, int y, RIuint32 coverage) const;	//rasterizer calls this function for each pixel
    void 	fillSolidSpan(int startX, int y, int nPixels) const;
    void	setDrawable(Drawable* drawable);
    void	setBlendMode(VGBlendMode blendMode);
    RI_INLINE VGBlendMode getBlendMode() const { return m_blendMode; }
    void    setRenderToMask(bool renderToMask) { m_renderToMask = renderToMask; }
    void    setMaskOperation(VGMaskOperation maskOperation) { m_maskOperation = maskOperation; }
    void	setMask(bool masking);
    void	setImage(Image* image, VGImageMode imageMode);	//image = NULL disables drawImage functionality
    void	setSurfaceToPaintMatrix(const Matrix3x3& surfaceToPaintMatrix);
    void	setSurfaceToImageMatrix(const Matrix3x3& surfaceToImageMatrix);
    void	setImageQuality(VGImageQuality imageQuality);
    void	setTileFillColor(const Color& c);
    void	setPaint(Paint* paint);
    void    setColorTransform(bool enable, RIfloat values[8]);
    bool    hasColorTransform() const { return m_colorTransform; }
    RI_INLINE const SignatureState& getSignatureState() const { return m_signatureState; }

    // Functions that determine parts of derived state.
    void    prepareSpanUniforms(bool aa);

    RI_INLINE VGPaintType getPaintType() const;
    RI_INLINE bool isMasking() const;
    void fillSpans(PPVariants& variants, const Span* spans, int nSpans) const;

    void    colorTransform(Color& c) const;
    void    setColorTransformChanged(bool changed) { m_colorTransformChanged = changed; } // make paint friend and this private!
    bool    colorTransformChanged() const { return m_colorTransformChanged; }
    RI_INLINE VGImageMode getImageMode() const { return m_imageMode; }

    RI_INLINE static bool isImageOnly(const SignatureState& state);

private:

    const Image*    getRenderTargetImage() const;
    VGImageFormat   getPreferredLUTFormat() const;

    void	prepareSolidFill();
    void    prepareCoverageFill();
    void    prepareLinearGradient();
    void    prepareRadialGradient();
    void    preparePattern();
    void    prepareImage(bool aa);
    void    prepareSignatureState();
    void    prepareRenderToMask();
    void	linearGradient(RIfloat& g, RIfloat& rho, RIfloat x, RIfloat y) const;
    void	radialGradient(RIfloat& g, RIfloat& rho, RIfloat x, RIfloat y) const;
    Color	colorRamp(RIfloat gradient, RIfloat rho) const;
    Color	blend(const Color& s, RIfloat ar, RIfloat ag, RIfloat ab, const Color& d, VGBlendMode blendMode) const;

    PixelPipe(const PixelPipe&);						//!< Not allowed.
    const PixelPipe& operator=(const PixelPipe&);		//!< Not allowed.

    Drawable*               m_drawable;
    bool					m_masking;
    Image*					m_image;
    // \todo LUT within the paint class broke constness of paint.
    Paint*			        m_paint;
    Paint					m_defaultPaint;
    VGBlendMode				m_blendMode;
    VGImageMode				m_imageMode;
    VGImageQuality			m_imageQuality;
    Color					m_tileFillColor;
    bool                    m_colorTransform;
    RIfloat                 m_colorTransformValues[8];
    RIint32                 m_iColorTransformValues[8];
    Matrix3x3				m_surfaceToPaintMatrix;
    Matrix3x3				m_surfaceToImageMatrix;
    Matrix3x3               m_paintToSurfaceMatrix;
    VGMaskOperation         m_maskOperation;
    bool                    m_renderToMask;
    bool                    m_colorTransformChanged;

public:

    enum { COLOR_TRANSFORM_BITS = 8 };
    enum { COLOR_TRANSFORM_ONE = (1<<COLOR_TRANSFORM_BITS) };
    enum { COLOR_TRANSFORM_MASK = (COLOR_TRANSFORM_ONE - 1) };
    enum { GRADIENT_BITS = 16 };
    enum { GRADIENT_MASK = (1<<GRADIENT_BITS)-1 };
    enum { SAMPLE_BITS = 8 };
    enum { SAMPLE_MASK = (1<<SAMPLE_BITS)-1 };

private:


    SignatureState          m_signatureState;
    SignatureState          m_derivedState;

    PPUniforms  m_spanUniforms;
};

RI_INLINE VGPaintType PixelPipe::getPaintType() const
{
    if (m_paint->m_paintType == VG_PAINT_TYPE_COLOR)
        return VG_PAINT_TYPE_COLOR;

    if (m_paint->m_paintType == VG_PAINT_TYPE_PATTERN && !m_paint->m_pattern)
        return VG_PAINT_TYPE_COLOR;

    if (m_paint->m_paintType == VG_PAINT_TYPE_LINEAR_GRADIENT && m_paint->linearDegenerate())
        return VG_PAINT_TYPE_COLOR;

    if (m_paint->m_paintType == VG_PAINT_TYPE_RADIAL_GRADIENT && m_paint->radialDegenerate())
        return VG_PAINT_TYPE_COLOR;

    return m_paint->m_paintType;
}

RI_INLINE bool PixelPipe::isMasking() const
{
    return m_masking;
}

RI_INLINE /*static*/ bool PixelPipe::isImageOnly(const SignatureState& state)
{
    if (state.hasImage)
        return (state.imageMode == VG_DRAW_IMAGE_NORMAL) ? true : false;
    else
        return false;
}

//=======================================================================

}	//namespace OpenVGRI

//=======================================================================

#endif /* __RIPIXELPIPE_H */