/* * Copyright © 2013 Raspberry Pi Foundation * Copyright © 2013 RISC OS Open Ltd * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of the copyright holders not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. The copyright holders make no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * */ #ifndef BITBLTINTERNAL_H_ #define BITBLTINTERNAL_H_ #include "BitBltDispatch.h" #define IGNORE(x) (void)(x) #define CACHELINE_LEN (32) /* These flags are named after properties that the operation has. * In the fast path table, the set bits are the flags that must *not* * be set. So if none of a group of related flag bits are set, then * the fast can handle any setting. If it can handle only one setting * within that group, then all other bits in that group are set (there * are some macros lower down to simplify specifying such fast paths). */ enum { FAST_PATH_SRC_0BPP = 1u<<0, FAST_PATH_SRC_1BPP = 1u<<1, FAST_PATH_SRC_2BPP = 1u<<2, FAST_PATH_SRC_4BPP = 1u<<3, FAST_PATH_SRC_8BPP = 1u<<4, FAST_PATH_SRC_16BPP = 1u<<5, FAST_PATH_SRC_32BPP = 1u<<6, FAST_PATH_SRC_BIG_ENDIAN = 1u<<7, FAST_PATH_SRC_LITTLE_ENDIAN = 1u<<8, FAST_PATH_DEST_1BPP = 1u<<9, FAST_PATH_DEST_2BPP = 1u<<10, FAST_PATH_DEST_4BPP = 1u<<11, FAST_PATH_DEST_8BPP = 1u<<12, FAST_PATH_DEST_16BPP = 1u<<13, FAST_PATH_DEST_32BPP = 1u<<14, FAST_PATH_DEST_BIG_ENDIAN = 1u<<15, FAST_PATH_DEST_LITTLE_ENDIAN = 1u<<16, FAST_PATH_NO_COLOR_MAP = 1u<<17, FAST_PATH_9BIT_COLOR_MAP = 1u<<18, FAST_PATH_12BIT_COLOR_MAP = 1u<<19, FAST_PATH_15BIT_COLOR_MAP = 1u<<20, FAST_PATH_DIRECT_COLOR_MAP = FAST_PATH_15BIT_COLOR_MAP, /* for use with <16bpp */ FAST_PATH_NO_HALFTONE = 1u<<21, FAST_PATH_SCALAR_HALFTONE = 1u<<22, FAST_PATH_VECTOR_HALFTONE = 1u<<23, FAST_PATH_CA_NO_GAMMA = 1u<<24, FAST_PATH_CA_HAS_GAMMA = 1u<<25, FAST_PATH_NO_OVERLAP = 1u<<26, FAST_PATH_H_OVERLAP = 1u<<27, FAST_PATH_V_OVERLAP = 1u<<28, }; /* These are the derived macros for use in specifying fast paths. */ #define ONLY_SRC_0BPP (FAST_PATH_SRC_1BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_16BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_1BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_16BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_2BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_1BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_16BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_4BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_1BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_16BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_8BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_1BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_16BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_16BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_1BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_32BPP) #define ONLY_SRC_32BPP (FAST_PATH_SRC_0BPP | FAST_PATH_SRC_1BPP | FAST_PATH_SRC_2BPP | FAST_PATH_SRC_4BPP | FAST_PATH_SRC_8BPP | FAST_PATH_SRC_16BPP) #define ONLY_SRC_BIG_ENDIAN (FAST_PATH_SRC_LITTLE_ENDIAN) #define ONLY_SRC_LITTLE_ENDIAN (FAST_PATH_SRC_LITTLE_ENDIAN) #define ONLY_DEST_1BPP (FAST_PATH_DEST_2BPP | FAST_PATH_DEST_4BPP | FAST_PATH_DEST_8BPP | FAST_PATH_DEST_16BPP | FAST_PATH_DEST_32BPP) #define ONLY_DEST_2BPP (FAST_PATH_DEST_1BPP | FAST_PATH_DEST_4BPP | FAST_PATH_DEST_8BPP | FAST_PATH_DEST_16BPP | FAST_PATH_DEST_32BPP) #define ONLY_DEST_4BPP (FAST_PATH_DEST_1BPP | FAST_PATH_DEST_2BPP | FAST_PATH_DEST_8BPP | FAST_PATH_DEST_16BPP | FAST_PATH_DEST_32BPP) #define ONLY_DEST_8BPP (FAST_PATH_DEST_1BPP | FAST_PATH_DEST_2BPP | FAST_PATH_DEST_4BPP | FAST_PATH_DEST_16BPP | FAST_PATH_DEST_32BPP) #define ONLY_DEST_16BPP (FAST_PATH_DEST_1BPP | FAST_PATH_DEST_2BPP | FAST_PATH_DEST_4BPP | FAST_PATH_DEST_8BPP | FAST_PATH_DEST_32BPP) #define ONLY_DEST_32BPP (FAST_PATH_DEST_1BPP | FAST_PATH_DEST_2BPP | FAST_PATH_DEST_4BPP | FAST_PATH_DEST_8BPP | FAST_PATH_DEST_16BPP) #define ONLY_DEST_BIG_ENDIAN (FAST_PATH_DEST_LITTLE_ENDIAN) #define ONLY_DEST_LITTLE_ENDIAN (FAST_PATH_DEST_LITTLE_ENDIAN) #define ONLY_NO_COLOR_MAP (FAST_PATH_9BIT_COLOR_MAP | FAST_PATH_12BIT_COLOR_MAP | FAST_PATH_15BIT_COLOR_MAP) #define ONLY_9BIT_COLOR_MAP (FAST_PATH_NO_COLOR_MAP | FAST_PATH_12BIT_COLOR_MAP | FAST_PATH_15BIT_COLOR_MAP) #define ONLY_12BIT_COLOR_MAP (FAST_PATH_NO_COLOR_MAP | FAST_PATH_9BIT_COLOR_MAP | FAST_PATH_15BIT_COLOR_MAP) #define ONLY_15BIT_COLOR_MAP (FAST_PATH_NO_COLOR_MAP | FAST_PATH_9BIT_COLOR_MAP | FAST_PATH_12BIT_COLOR_MAP) #define ONLY_DIRECT_COLOR_MAP ONLY_15BIT_COLOR_MAP /* for use with <16bpp */ #define ONLY_NO_HALFTONE (FAST_PATH_SCALAR_HALFTONE | FAST_PATH_VECTOR_HALFTONE) #define ONLY_SCALAR_HALFTONE (FAST_PATH_NO_HALFTONE | FAST_PATH_VECTOR_HALFTONE) #define ONLY_VECTOR_HALFTONE (FAST_PATH_NO_HALFTONE | FAST_PATH_SCALAR_HALFTONE) #define ONLY_CA_NO_GAMMA (FAST_PATH_CA_HAS_GAMMA) #define ONLY_CA_HAS_GAMMA (FAST_PATH_CA_NO_GAMMA) #define ONLY_NO_OVERLAP (FAST_PATH_H_OVERLAP | FAST_PATH_V_OVERLAP) #define ONLY_H_OVERLAP (FAST_PATH_NO_OVERLAP | FAST_PATH_V_OVERLAP) #define ONLY_V_OVERLAP (FAST_PATH_NO_OVERLAP | FAST_PATH_H_OVERLAP) #define STD_FLAGS(src_bpp, dest_bpp, map_type, halftone_type) (ONLY_SRC_##src_bpp##BPP | ONLY_SRC_BIG_ENDIAN | ONLY_DEST_##dest_bpp##BPP | ONLY_DEST_BIG_ENDIAN | ONLY_##map_type##_COLOR_MAP | ONLY_##halftone_type##_HALFTONE | ONLY_NO_OVERLAP) #define STD_FLAGS_NO_SOURCE(dest_bpp, halftone_type) (ONLY_SRC_0BPP | ONLY_DEST_##dest_bpp##BPP | ONLY_DEST_BIG_ENDIAN | ONLY_##halftone_type##_HALFTONE) /** This macro basically tells the compiler that the pointer to the * "op" structure doesn't alias with any other pointers. I'd use the * restrict keyword instead, but Squeak is built C89. */ #define COPY_OP_TO_LOCALS(op, src_type, dest_type) \ combination_rule_t combinationRule = op->combinationRule; \ bool noSource = op->noSource; \ src_type *srcBits = op->src.bits; \ uint32_t srcDepth = op->src.depth; \ uint32_t srcPitch = op->src.pitch / sizeof (src_type); \ bool srcMSB = op->src.msb; \ uint32_t srcX = op->src.x; \ uint32_t srcY = op->src.y; \ dest_type *destBits = op->dest.bits; \ uint32_t destDepth = op->dest.depth; \ uint32_t destPitch = op->dest.pitch / sizeof (dest_type); \ bool destMSB = op->dest.msb; \ uint32_t destX = op->dest.x; \ uint32_t destY = op->dest.y; \ uint32_t width = op->width; \ uint32_t height = op->height; \ uint32_t cmFlags = op->cmFlags; \ int32_t (*cmShiftTable)[4] = op->cmShiftTable; \ uint32_t (*cmMaskTable)[4] = op->cmMaskTable; \ uint32_t cmMask = op->cmMask; \ uint32_t (*cmLookupTable)[] = op->cmLookupTable; \ bool noHalftone = op->noHalftone; \ uint32_t halftoneHeight = op->halftoneHeight; \ uint32_t (*halftoneBase)[] = (uint32_t (*)[]) op->halftoneBase; \ IGNORE(combinationRule); \ IGNORE(noSource); \ IGNORE(srcBits); \ IGNORE(srcDepth); \ IGNORE(srcPitch); \ IGNORE(srcMSB); \ IGNORE(srcX); \ IGNORE(srcY); \ IGNORE(destBits); \ IGNORE(destDepth); \ IGNORE(destPitch); \ IGNORE(destMSB); \ IGNORE(destX); \ IGNORE(destY); \ IGNORE(width); \ IGNORE(height); \ IGNORE(cmFlags); \ IGNORE(cmShiftTable); \ IGNORE(cmMaskTable); \ IGNORE(cmMask); \ IGNORE(cmLookupTable); \ IGNORE(noHalftone); \ IGNORE(halftoneHeight); \ IGNORE(halftoneBase); \ typedef struct { void (*func)(operation_t *, uint32_t); combination_rule_t combinationRule; uint32_t flags; } fast_path_t; void addFastPaths(fast_path_t *paths, size_t n); void (*lookupFastPath(combination_rule_t combinationRule, uint32_t flags))(operation_t *, uint32_t); void copyBitsFallback(operation_t *op, uint32_t flags); #endif /* BITBLTINTERNAL_H_ */