michael@0: michael@0: /* michael@0: * Copyright 2007 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkBitmapProcState_DEFINED michael@0: #define SkBitmapProcState_DEFINED michael@0: michael@0: #include "SkBitmap.h" michael@0: #include "SkBitmapFilter.h" michael@0: #include "SkMatrix.h" michael@0: #include "SkPaint.h" michael@0: #include "SkScaledImageCache.h" michael@0: michael@0: #define FractionalInt_IS_64BIT michael@0: michael@0: #ifdef FractionalInt_IS_64BIT michael@0: typedef SkFixed48 SkFractionalInt; michael@0: #define SkScalarToFractionalInt(x) SkScalarToFixed48(x) michael@0: #define SkFractionalIntToFixed(x) SkFixed48ToFixed(x) michael@0: #define SkFixedToFractionalInt(x) SkFixedToFixed48(x) michael@0: #define SkFractionalIntToInt(x) SkFixed48ToInt(x) michael@0: #else michael@0: typedef SkFixed SkFractionalInt; michael@0: #define SkScalarToFractionalInt(x) SkScalarToFixed(x) michael@0: #define SkFractionalIntToFixed(x) (x) michael@0: #define SkFixedToFractionalInt(x) (x) michael@0: #define SkFractionalIntToInt(x) ((x) >> 16) michael@0: #endif michael@0: michael@0: class SkPaint; michael@0: struct SkConvolutionProcs; michael@0: michael@0: struct SkBitmapProcState { michael@0: michael@0: SkBitmapProcState(): fScaledCacheID(NULL), fBitmapFilter(NULL) {} michael@0: ~SkBitmapProcState(); michael@0: michael@0: typedef void (*ShaderProc32)(const SkBitmapProcState&, int x, int y, michael@0: SkPMColor[], int count); michael@0: michael@0: typedef void (*ShaderProc16)(const SkBitmapProcState&, int x, int y, michael@0: uint16_t[], int count); michael@0: michael@0: typedef void (*MatrixProc)(const SkBitmapProcState&, michael@0: uint32_t bitmapXY[], michael@0: int count, michael@0: int x, int y); michael@0: michael@0: typedef void (*SampleProc32)(const SkBitmapProcState&, michael@0: const uint32_t[], michael@0: int count, michael@0: SkPMColor colors[]); michael@0: michael@0: typedef void (*SampleProc16)(const SkBitmapProcState&, michael@0: const uint32_t[], michael@0: int count, michael@0: uint16_t colors[]); michael@0: michael@0: typedef U16CPU (*FixedTileProc)(SkFixed); // returns 0..0xFFFF michael@0: typedef U16CPU (*FixedTileLowBitsProc)(SkFixed, int); // returns 0..0xF michael@0: typedef U16CPU (*IntTileProc)(int value, int count); // returns 0..count-1 michael@0: michael@0: const SkBitmap* fBitmap; // chooseProcs - orig or scaled michael@0: SkMatrix fInvMatrix; // chooseProcs michael@0: SkMatrix::MapXYProc fInvProc; // chooseProcs michael@0: michael@0: SkFractionalInt fInvSxFractionalInt; michael@0: SkFractionalInt fInvKyFractionalInt; michael@0: michael@0: FixedTileProc fTileProcX; // chooseProcs michael@0: FixedTileProc fTileProcY; // chooseProcs michael@0: FixedTileLowBitsProc fTileLowBitsProcX; // chooseProcs michael@0: FixedTileLowBitsProc fTileLowBitsProcY; // chooseProcs michael@0: IntTileProc fIntTileProcY; // chooseProcs michael@0: SkFixed fFilterOneX; michael@0: SkFixed fFilterOneY; michael@0: michael@0: SkPMColor fPaintPMColor; // chooseProcs - A8 config michael@0: SkFixed fInvSx; // chooseProcs michael@0: SkFixed fInvKy; // chooseProcs michael@0: uint16_t fAlphaScale; // chooseProcs michael@0: uint8_t fInvType; // chooseProcs michael@0: uint8_t fTileModeX; // CONSTRUCTOR michael@0: uint8_t fTileModeY; // CONSTRUCTOR michael@0: uint8_t fFilterLevel; // chooseProcs michael@0: michael@0: /** The shader will let us know when we can release some of our resources michael@0: * like scaled bitmaps. michael@0: */ michael@0: michael@0: void endContext(); michael@0: michael@0: /** Platforms implement this, and can optionally overwrite only the michael@0: following fields: michael@0: michael@0: fShaderProc32 michael@0: fShaderProc16 michael@0: fMatrixProc michael@0: fSampleProc32 michael@0: fSampleProc32 michael@0: michael@0: They will already have valid function pointers, so a platform that does michael@0: not have an accelerated version can just leave that field as is. A valid michael@0: implementation can do nothing (see SkBitmapProcState_opts_none.cpp) michael@0: */ michael@0: void platformProcs(); michael@0: michael@0: /** Platforms can also optionally overwrite the convolution functions michael@0: if we have SIMD versions of them. michael@0: */ michael@0: michael@0: void platformConvolutionProcs(SkConvolutionProcs*); michael@0: michael@0: /** Given the byte size of the index buffer to be passed to the matrix proc, michael@0: return the maximum number of resulting pixels that can be computed michael@0: (i.e. the number of SkPMColor values to be written by the sample proc). michael@0: This routine takes into account that filtering and scale-vs-affine michael@0: affect the amount of buffer space needed. michael@0: michael@0: Only valid to call after chooseProcs (setContext) has been called. It is michael@0: safe to call this inside the shader's shadeSpan() method. michael@0: */ michael@0: int maxCountForBufferSize(size_t bufferSize) const; michael@0: michael@0: // If a shader proc is present, then the corresponding matrix/sample procs michael@0: // are ignored michael@0: ShaderProc32 getShaderProc32() const { return fShaderProc32; } michael@0: ShaderProc16 getShaderProc16() const { return fShaderProc16; } michael@0: michael@0: SkBitmapFilter* getBitmapFilter() const { return fBitmapFilter; } michael@0: michael@0: #ifdef SK_DEBUG michael@0: MatrixProc getMatrixProc() const; michael@0: #else michael@0: MatrixProc getMatrixProc() const { return fMatrixProc; } michael@0: #endif michael@0: SampleProc32 getSampleProc32() const { return fSampleProc32; } michael@0: SampleProc16 getSampleProc16() const { return fSampleProc16; } michael@0: michael@0: private: michael@0: friend class SkBitmapProcShader; michael@0: michael@0: ShaderProc32 fShaderProc32; // chooseProcs michael@0: ShaderProc16 fShaderProc16; // chooseProcs michael@0: // These are used if the shaderproc is NULL michael@0: MatrixProc fMatrixProc; // chooseProcs michael@0: SampleProc32 fSampleProc32; // chooseProcs michael@0: SampleProc16 fSampleProc16; // chooseProcs michael@0: michael@0: SkBitmap fOrigBitmap; // CONSTRUCTOR michael@0: SkBitmap fScaledBitmap; // chooseProcs michael@0: michael@0: SkScaledImageCache::ID* fScaledCacheID; michael@0: michael@0: MatrixProc chooseMatrixProc(bool trivial_matrix); michael@0: bool chooseProcs(const SkMatrix& inv, const SkPaint&); michael@0: ShaderProc32 chooseShaderProc32(); michael@0: michael@0: // returns false if we did not try to scale the image. In that case, we michael@0: // will need to "lock" its pixels some other way. michael@0: bool possiblyScaleImage(); michael@0: michael@0: // returns false if we failed to "lock" the pixels at all. Typically this michael@0: // means we have to abort the shader. michael@0: bool lockBaseBitmap(); michael@0: michael@0: SkBitmapFilter* fBitmapFilter; michael@0: michael@0: // If supported, sets fShaderProc32 and fShaderProc16 and returns true, michael@0: // otherwise returns false. michael@0: bool setBitmapFilterProcs(); michael@0: michael@0: // Return false if we failed to setup for fast translate (e.g. overflow) michael@0: bool setupForTranslate(); michael@0: michael@0: #ifdef SK_DEBUG michael@0: static void DebugMatrixProc(const SkBitmapProcState&, michael@0: uint32_t[], int count, int x, int y); michael@0: #endif michael@0: }; michael@0: michael@0: /* Macros for packing and unpacking pairs of 16bit values in a 32bit uint. michael@0: Used to allow access to a stream of uint16_t either one at a time, or michael@0: 2 at a time by unpacking a uint32_t michael@0: */ michael@0: #ifdef SK_CPU_BENDIAN michael@0: #define PACK_TWO_SHORTS(pri, sec) ((pri) << 16 | (sec)) michael@0: #define UNPACK_PRIMARY_SHORT(packed) ((uint32_t)(packed) >> 16) michael@0: #define UNPACK_SECONDARY_SHORT(packed) ((packed) & 0xFFFF) michael@0: #else michael@0: #define PACK_TWO_SHORTS(pri, sec) ((pri) | ((sec) << 16)) michael@0: #define UNPACK_PRIMARY_SHORT(packed) ((packed) & 0xFFFF) michael@0: #define UNPACK_SECONDARY_SHORT(packed) ((uint32_t)(packed) >> 16) michael@0: #endif michael@0: michael@0: #ifdef SK_DEBUG michael@0: static inline uint32_t pack_two_shorts(U16CPU pri, U16CPU sec) { michael@0: SkASSERT((uint16_t)pri == pri); michael@0: SkASSERT((uint16_t)sec == sec); michael@0: return PACK_TWO_SHORTS(pri, sec); michael@0: } michael@0: #else michael@0: #define pack_two_shorts(pri, sec) PACK_TWO_SHORTS(pri, sec) michael@0: #endif michael@0: michael@0: // These functions are generated via macros, but are exposed here so that michael@0: // platformProcs may test for them by name. michael@0: void S32_opaque_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[], michael@0: int count, SkPMColor colors[]); michael@0: void S32_alpha_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[], michael@0: int count, SkPMColor colors[]); michael@0: void S32_opaque_D32_filter_DXDY(const SkBitmapProcState& s, michael@0: const uint32_t xy[], int count, SkPMColor colors[]); michael@0: void S32_alpha_D32_filter_DXDY(const SkBitmapProcState& s, michael@0: const uint32_t xy[], int count, SkPMColor colors[]); michael@0: void ClampX_ClampY_filter_scale(const SkBitmapProcState& s, uint32_t xy[], michael@0: int count, int x, int y); michael@0: void ClampX_ClampY_nofilter_scale(const SkBitmapProcState& s, uint32_t xy[], michael@0: int count, int x, int y); michael@0: void ClampX_ClampY_filter_affine(const SkBitmapProcState& s, michael@0: uint32_t xy[], int count, int x, int y); michael@0: void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s, michael@0: uint32_t xy[], int count, int x, int y); michael@0: void S32_D16_filter_DX(const SkBitmapProcState& s, michael@0: const uint32_t* xy, int count, uint16_t* colors); michael@0: michael@0: void highQualityFilter32(const SkBitmapProcState &s, int x, int y, michael@0: SkPMColor *SK_RESTRICT colors, int count); michael@0: void highQualityFilter16(const SkBitmapProcState &s, int x, int y, michael@0: uint16_t *SK_RESTRICT colors, int count); michael@0: michael@0: michael@0: #endif