diff -r 39e5f73667ba -r c2ef9095503a hostsupport/hostopenvg/src/riPixelPipe.h --- /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<= 0); return m_referenceCount; } + void setColor(const Color& color) {m_paintColor = color; m_paintColor.clamp(); m_paintColor.premultiply(); } + void setGradientStops(Array& inputStops, Array& 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 m_colorRampStops; + Array 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<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 */