hostsupport/hostopenvg/src/riPixelPipe.h
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 24 a3f46bb01be2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostopenvg/src/riPixelPipe.h	Wed Oct 06 17:59:01 2010 +0100
@@ -0,0 +1,428 @@
+#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 */