hostsupport/hostopenvg/src/riRasterizer.h
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 24 a3f46bb01be2
child 73 11fc086941ac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hostsupport/hostopenvg/src/riRasterizer.h	Wed Oct 06 17:59:01 2010 +0100
@@ -0,0 +1,279 @@
+#ifndef __RIRASTERIZER_H
+#define __RIRASTERIZER_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   Rasterizer class.
+ * \note
+ *//*-------------------------------------------------------------------*/
+
+#ifndef __RIMATH_H
+#include "riMath.h"
+#endif
+
+#ifndef __RIARRAY_H
+#include "riArray.h"
+#endif
+
+#ifndef __RIPIXELPIPE_H
+#include "riPixelPipe.h"
+#endif
+
+// TESTING ONLY!!
+#include "sfDynamicPixelPipe.h"
+
+#if defined(RI_DEBUG)
+#    include <stdio.h>
+#endif
+// \todo SSE2 probably has everything necessary and matches the minimum platform requirements.
+// SSE4 is probably too new. SSE3?
+// \note This will cause the code to not compile on MSVC...
+#define USE_SSE2
+
+#if defined(USE_SSE2)
+// \todo only the last include is needed: QT creator does not find types if others not included.
+#   include <mmintrin.h>
+#   include <xmmintrin.h>
+#   include <emmintrin.h>
+#endif
+
+//=======================================================================
+
+namespace OpenVGRI
+{
+
+/*-------------------------------------------------------------------*//*!
+* \brief    Scalar and vector data types used by the rasterizer.
+* \param
+* \return
+* \note
+*//*-------------------------------------------------------------------*/
+
+typedef RIfloat RScalar;    //change this if you want to have different precision for rasterizer scalars and RIfloat
+
+struct RVector2
+{
+    RI_INLINE RVector2()                            { }
+    RI_INLINE RVector2(const Vector2& v)            { x = v.x; y = v.y; }
+    RI_INLINE RVector2(RIfloat vx, RIfloat vy)      { x = vx; y = vy; }
+    RI_INLINE void set(RIfloat vx, RIfloat vy)      { x = vx; y = vy; }
+    RScalar     x;
+    RScalar     y;
+};
+
+struct IVector2
+{
+    RI_INLINE IVector2() {}
+    RI_INLINE IVector2(const IVector2& v) { x = v.x; y = v.y; }
+    RI_INLINE IVector2(const Vector2& v) { x = (int)v.x; y = (int) v.y; }
+    RI_INLINE IVector2(int vx, int vy) { x = vx; y = vy; }
+    RI_INLINE void set(int vx, int vy) { x = vx; y = vy; }
+    int x;
+    int y;
+};
+
+struct Span
+{
+    RIuint16 x0;
+    RIuint16 y;
+    RIuint16 len;
+    RIuint8  coverage;
+    RIuint8  pad; // align to 8 bytes. \temp Use qualifiers instead?
+};
+
+/*-------------------------------------------------------------------*//*!
+* \brief    Converts a set of edges to coverage values for each pixel and
+*           calls PixelPipe::pixelPipe for painting a pixel.
+* \param
+* \return
+* \note
+*//*-------------------------------------------------------------------*/
+
+class Rasterizer
+{
+public:
+    Rasterizer();   //throws bad_alloc
+    ~Rasterizer();
+
+    void        setup(int vpx, int vpy, int vpwidth, int vpheight, VGFillRule fillRule, const PixelPipe* pixelPipe);
+    void        setScissor(const Array<Rectangle>& scissors);   //throws bad_alloc
+    void        setScissoring(bool enabled);
+
+    void        clear();
+    void        addEdge(const Vector2& v0, const Vector2& v1);  //throws bad_alloc
+
+    RI_INLINE void setAntiAliasing(bool enable) { m_aa = enable; }
+    void        fill(); //throws bad_alloc
+
+    void        getBBox(int& sx, int& sy, int& ex, int& ey) const       { sx = m_covMinx; sy = m_covMiny; ex = m_covMaxx; ey = m_covMaxy; }
+
+public:
+    enum { SAMPLE_BITS = 3 };
+    enum { Y_BITS = SAMPLE_BITS };
+    enum { MAX_COVERAGE = 1<<SAMPLE_BITS };
+
+    // temp!:
+    RIuint32    *m_covBuffer;
+    size_t      m_covBufferSz;
+
+private:
+    Rasterizer(const Rasterizer&);                      //!< Not allowed.
+    const Rasterizer& operator=(const Rasterizer&);     //!< Not allowed.
+
+public:
+    struct ScissorEdge
+    {
+        ScissorEdge() {}
+        bool operator<(const ScissorEdge& e) const  { return x < e.x; }
+        int         x;
+        int         miny;
+        int         maxy;
+        int         direction;      //1 start, -1 end
+    };
+
+    struct Edge
+    {
+        Edge() {}
+        bool operator<(const Edge& e) const { return v0.y < e.v0.y; }
+#if defined(RI_DEBUG)
+        bool operator<=(const Edge& e) const {return v0.y <= e.v0.y; }
+#endif
+        IVector2    v0;
+        IVector2    v1;
+        int         direction;
+    };
+
+    struct ActiveEdge
+    {
+        typedef RIint16 XCoord;
+        typedef RIint16 YCoord;
+
+        ActiveEdge() {}
+        //bool operator<(const ActiveEdge& e) const   { return minx < e.minx; }
+        bool operator<(const ActiveEdge& e) const
+        {
+            if (minx < e.minx)
+                return true;
+            if (minx == e.minx)
+                return maxx < e.maxx;
+            return false;
+        }
+#if defined(RI_DEBUG)
+        bool operator<=(const ActiveEdge& e) const { return minx <= e.minx; }
+#endif
+        // Fixed-point edge coordinates.
+        RIuint32 next; // \todo Pointer?
+        int     direction;      //-1 down, 1 up
+        int     xRef;
+        int     slope;
+        XCoord  minx;           // for the current scanline
+        XCoord  maxx;           // for the current scanline
+        YCoord  yStart;         // for the edge
+        YCoord  yEnd;           // for the edge
+    };
+
+    enum { SF_SAMPLES = 8 };
+    enum { RASTERIZER_BITS = 14 };
+    enum { RASTERIZER_MASK = ((1<<RASTERIZER_BITS)-1) };
+    enum { Y_MASK = ((1<<Y_BITS)-1) };
+    enum { X_BITS = 7 };
+    enum { XMASK  = ((1<<X_BITS)-1) };
+    enum { LEFT_DISCARD = -0x100000 };
+    enum { LEFT_DISCARD_SHORT = -32768 };
+
+    struct Windings
+    {
+#if !defined(USE_SSE2)
+        Windings() {wq = 0;}
+        // \todo Use SSE counters or packed counters!
+        // \todo 8 samples -> 64 bits == 2 32-bit uints
+        union
+        {
+            RIint8              winding[SF_SAMPLES];
+            RIuint32            wd[SF_SAMPLES/4];
+            unsigned long long  wq;
+        };
+#else
+        Windings() { sseWinding = _mm_setzero_si128(); }
+        __m128i sseWinding;
+#endif
+     };
+
+private:
+    void                pushEdge(const Edge& edge);
+    void                clipAndAddEdge(Edge& edge);
+    void                addBBox(const IVector2& v);
+    RI_INLINE void      pushSpan(int x, int y, int len, int coverage);
+    RI_INLINE void      commitSpans();
+
+    //RI_INLINE void      calculateAEWinding(const ActiveEdge& currAe, Windings& pixel, Windings& scanline, int intY, int pixelX);
+
+    Array<ActiveEdge>   m_edgePool;
+    Array<RIuint32>     m_edges;
+    Array<ScissorEdge>  m_scissorEdges;
+    Array<ActiveEdge>   m_aet;
+    Array<ScissorEdge>  m_scissorAet;
+    bool                m_scissor;
+
+    bool                    m_aa;
+
+    IVector2            m_edgeMin;
+    IVector2            m_edgeMax;
+    int                 m_covMinx;
+    int                 m_covMiny;
+    int                 m_covMaxx;
+    int                 m_covMaxy;
+    int                 m_vpx;
+    int                 m_vpy;
+    int                 m_vpwidth;
+    int                 m_vpheight;
+    int                 m_vpMinx;
+    int                 m_vpMiny;
+    int                 m_vpMaxx;
+    int                 m_vpMaxy;
+    VGFillRule          m_fillRule;
+    RIuint32            m_fillRuleMask;
+
+    const PixelPipe*        m_pixelPipe;
+    PixelPipe::PPVariants   m_ppVariants;
+
+    enum { N_CACHED_SPANS = 64 };
+    Span                m_spanCache[N_CACHED_SPANS];
+    int                 m_nSpans;
+
+};
+
+//=======================================================================
+
+}   //namespace OpenVGRI
+
+//=======================================================================
+
+#endif /* __RIRASTERIZER_H */