--- a/holdingarea/vg/2D_OpenVG_1_1_SF/ri/src/sfDynamicBlitter.cpp Thu Sep 16 12:43:44 2010 +0100
+++ b/holdingarea/vg/2D_OpenVG_1_1_SF/ri/src/sfDynamicBlitter.cpp Mon Sep 20 14:29:05 2010 +0100
@@ -1,217 +1,217 @@
-/* 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.
- */
-
-#include "sfDynamicBlitter.h"
-
-#ifndef __SFBLITTER_H
-# include "sfBlitter.h"
-#endif
-
-#ifndef __SFMASK_H
-# include "sfMask.h"
-#endif
-
-namespace OpenVGRI {
-
-RI_INLINE static bool maskOperationRequiresLoad(VGMaskOperation op)
-{
- switch(op)
- {
- case VG_CLEAR_MASK:
- case VG_FILL_MASK:
- case VG_SET_MASK:
- return false;
- default:
- RI_ASSERT(op == VG_UNION_MASK || op == VG_INTERSECT_MASK || op == VG_SUBTRACT_MASK);
- return true;
- }
-}
-
-/**
- * \brief Blit rectangular areas between similar or different color format buffers.
- * \note Implementation is structured so that the per-pixel branches are minimized
- * even if dynamic compilation is not in use.
- * \todo For some reason the completely generic integer conversion does not optimize
- * fully run-time. Check what causes this!
- */
-void executeBlitter(const DynamicBlitter::BlitSignatureState& state, const DynamicBlitter::BlitUniforms& uniforms)
-{
- const void* srcPtr = Image::calculateAddress(
- uniforms.src, state.srcDesc.bitsPerPixel, uniforms.srcX, uniforms.srcY, uniforms.srcStride);
- void* dstPtr = Image::calculateAddress(
- uniforms.dst, state.dstDesc.bitsPerPixel, uniforms.dstX, uniforms.dstY, uniforms.dstStride);
-
- // The following flag is useful for debugging. Enabling it will hurt performance.
-//#define ALWAYS_FORCE_FULL_CONVERSION
-
- // Currently the data must be byte-aligned for memcpy optimizations:
- const int minBpp = RI_INT_MIN(state.srcDesc.bitsPerPixel, state.dstDesc.bitsPerPixel);
- const bool byteCopy = minBpp >= 8 ? true : false;
- const bool forceFullConversion = state.isMaskOperation || state.unsafeInput || !byteCopy;
-
-#if !defined(ALWAYS_FORCE_FULL_CONVERSION)
- if (state.srcDesc.isZeroConversion(state.dstDesc) && !forceFullConversion)
- {
- const int fullCopyStride = Image::descriptorToStride(state.srcDesc, uniforms.width);
-
- if ((uniforms.dstStride != uniforms.srcStride) || (fullCopyStride != uniforms.srcStride))
- {
- // memcpy individual scanlines.
- const size_t scanLength = (size_t)RI_INT_ABS(Image::descriptorToStride(state.srcDesc, uniforms.width));
- for (RIuint32 i = 0; i < uniforms.height; i++)
- {
- memcpy(dstPtr, srcPtr, scanLength);
- dstPtr = (void*)((RIuint8*)dstPtr + uniforms.dstStride);
- srcPtr = (void*)((RIuint8*)srcPtr + uniforms.srcStride);
- }
- } else
- {
- // memcpy the whole area
- memcpy(dstPtr, srcPtr, uniforms.srcStride * uniforms.height);
- }
- } else if (state.srcDesc.isShiftConversion(state.dstDesc) && !forceFullConversion)
- {
- // \todo Separate to function? Replace with pointer read/write & advance.
- if (state.srcDesc.isShiftConversionToLower(state.dstDesc))
- {
- // Components can be immediately shifted down to lower bit-depth.
- for (RIuint32 j = 0; j < uniforms.height; j++)
- {
- RIuint8* srcStart = (RIuint8*)srcPtr;
- RIuint8* dstStart = (RIuint8*)dstPtr;
- RIuint32 srcX = uniforms.srcX;
- RIuint32 dstX = uniforms.dstX;
- for (RIuint32 i = 0; i < uniforms.width; i++)
- {
- RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX); // \todo srcX!
- RIuint32 dc = Color::Descriptor::crossConvertToLower(c, state.srcDesc, state.dstDesc);
- Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
-
- srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
- dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
-
- srcX++;
- dstX++;
- }
- srcPtr = (void*)(srcStart + uniforms.srcStride);
- dstPtr = (void*)(dstStart + uniforms.dstStride);
- }
- }
- else
- {
- // Color components require expansion before shifting to destination color-format */
- for (RIuint32 j = 0; j < uniforms.height; j++)
- {
- RIuint8* srcStart = (RIuint8*)srcPtr;
- RIuint8* dstStart = (RIuint8*)dstPtr;
- RIuint32 srcX = uniforms.srcX;
- RIuint32 dstX = uniforms.dstX;
- for (RIuint32 i = 0; i < uniforms.width; i++)
- {
- RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX);
- IntegerColor ic = IntegerColor(c, state.srcDesc);
- ic.expandColor(state.srcDesc);
- ic.truncateColor(state.dstDesc);
- RIuint32 dc = ic.getPackedColor(state.dstDesc);
- Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
-
- srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
- dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
-
- srcX++;
- dstX++;
- }
- srcPtr = (void*)(srcStart + uniforms.srcStride);
- dstPtr = (void*)(dstStart + uniforms.dstStride);
- }
- }
- } else
-#endif
- {
- /* This block should handle the rest (and all) of the color-conversion cases. */
- for (RIuint32 j = 0; j < uniforms.height; j++)
- {
- RIuint8* srcStart = (RIuint8*)srcPtr;
- RIuint8* dstStart = (RIuint8*)dstPtr;
- RIuint32 srcX = uniforms.srcX;
- RIuint32 dstX = uniforms.dstX;
- for (RIuint32 i = 0; i < uniforms.width; i++)
- {
- RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX);
- IntegerColor ic;
- RIuint32 dc;
-
- if (!state.isMaskOperation)
- {
- ic = IntegerColor(c, state.srcDesc);
- if (state.unsafeInput)
- ic.clampToAlpha();
-
- ic.convertToFrom(state.dstDesc, state.srcDesc, false);
- dc = ic.getPackedColor(state.dstDesc);
- }
- else
- {
- // Apply the given mask operation between two surfaces.
- IntegerColor id;
-
- if (maskOperationRequiresLoad(state.maskOperation))
- {
- ic.fromPackedMask(c, state.srcDesc);
- ic.expandMask(state.srcDesc);
-
- IntegerColor id;
-
- RIuint32 d = Image::readPackedPixelFromAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX);
- id.fromPackedMask(d, state.dstDesc);
- id.expandColor(state.dstDesc);
-
- RIuint32 coverage = ic.a + (ic.a >> 7);
- ic = intMaskOperation(coverage, id, state.maskOperation);
- }
- else
- {
- // Other ops handled with memset, not blitter
- RI_ASSERT(state.maskOperation == VG_SET_MASK);
- ic.fromPackedMask(c, state.srcDesc);
- //ic.expandMask(state.srcDesc);
- ic.convertToFrom(state.dstDesc, state.srcDesc, true);
- }
- dc = ic.getPackedMaskColor(state.dstDesc);
- }
-
- Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
-
- srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
- dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
-
- srcX++;
- dstX++;
- }
- srcPtr = (void*)(srcStart + uniforms.srcStride);
- dstPtr = (void*)(dstStart + uniforms.dstStride);
- }
- }
-}
-
-}
-
+/* 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.
+ */
+
+#include "sfDynamicBlitter.h"
+
+#ifndef __SFBLITTER_H
+# include "sfBlitter.h"
+#endif
+
+#ifndef __SFMASK_H
+# include "sfMask.h"
+#endif
+
+namespace OpenVGRI {
+
+RI_INLINE static bool maskOperationRequiresLoad(VGMaskOperation op)
+{
+ switch(op)
+ {
+ case VG_CLEAR_MASK:
+ case VG_FILL_MASK:
+ case VG_SET_MASK:
+ return false;
+ default:
+ RI_ASSERT(op == VG_UNION_MASK || op == VG_INTERSECT_MASK || op == VG_SUBTRACT_MASK);
+ return true;
+ }
+}
+
+/**
+ * \brief Blit rectangular areas between similar or different color format buffers.
+ * \note Implementation is structured so that the per-pixel branches are minimized
+ * even if dynamic compilation is not in use.
+ * \todo For some reason the completely generic integer conversion does not optimize
+ * fully run-time. Check what causes this!
+ */
+void executeBlitter(const DynamicBlitter::BlitSignatureState& state, const DynamicBlitter::BlitUniforms& uniforms)
+{
+ const void* srcPtr = Image::calculateAddress(
+ uniforms.src, state.srcDesc.bitsPerPixel, uniforms.srcX, uniforms.srcY, uniforms.srcStride);
+ void* dstPtr = Image::calculateAddress(
+ uniforms.dst, state.dstDesc.bitsPerPixel, uniforms.dstX, uniforms.dstY, uniforms.dstStride);
+
+ // The following flag is useful for debugging. Enabling it will hurt performance.
+//#define ALWAYS_FORCE_FULL_CONVERSION
+
+ // Currently the data must be byte-aligned for memcpy optimizations:
+ const int minBpp = RI_INT_MIN(state.srcDesc.bitsPerPixel, state.dstDesc.bitsPerPixel);
+ const bool byteCopy = minBpp >= 8 ? true : false;
+ const bool forceFullConversion = state.isMaskOperation || state.unsafeInput || !byteCopy;
+
+#if !defined(ALWAYS_FORCE_FULL_CONVERSION)
+ if (state.srcDesc.isZeroConversion(state.dstDesc) && !forceFullConversion)
+ {
+ const int fullCopyStride = Image::descriptorToStride(state.srcDesc, uniforms.width);
+
+ if ((uniforms.dstStride != uniforms.srcStride) || (fullCopyStride != uniforms.srcStride))
+ {
+ // memcpy individual scanlines.
+ const size_t scanLength = (size_t)RI_INT_ABS(Image::descriptorToStride(state.srcDesc, uniforms.width));
+ for (RIuint32 i = 0; i < uniforms.height; i++)
+ {
+ memcpy(dstPtr, srcPtr, scanLength);
+ dstPtr = (void*)((RIuint8*)dstPtr + uniforms.dstStride);
+ srcPtr = (void*)((RIuint8*)srcPtr + uniforms.srcStride);
+ }
+ } else
+ {
+ // memcpy the whole area
+ memcpy(dstPtr, srcPtr, uniforms.srcStride * uniforms.height);
+ }
+ } else if (state.srcDesc.isShiftConversion(state.dstDesc) && !forceFullConversion)
+ {
+ // \todo Separate to function? Replace with pointer read/write & advance.
+ if (state.srcDesc.isShiftConversionToLower(state.dstDesc))
+ {
+ // Components can be immediately shifted down to lower bit-depth.
+ for (RIuint32 j = 0; j < uniforms.height; j++)
+ {
+ RIuint8* srcStart = (RIuint8*)srcPtr;
+ RIuint8* dstStart = (RIuint8*)dstPtr;
+ RIuint32 srcX = uniforms.srcX;
+ RIuint32 dstX = uniforms.dstX;
+ for (RIuint32 i = 0; i < uniforms.width; i++)
+ {
+ RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX); // \todo srcX!
+ RIuint32 dc = Color::Descriptor::crossConvertToLower(c, state.srcDesc, state.dstDesc);
+ Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
+
+ srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
+ dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
+
+ srcX++;
+ dstX++;
+ }
+ srcPtr = (void*)(srcStart + uniforms.srcStride);
+ dstPtr = (void*)(dstStart + uniforms.dstStride);
+ }
+ }
+ else
+ {
+ // Color components require expansion before shifting to destination color-format */
+ for (RIuint32 j = 0; j < uniforms.height; j++)
+ {
+ RIuint8* srcStart = (RIuint8*)srcPtr;
+ RIuint8* dstStart = (RIuint8*)dstPtr;
+ RIuint32 srcX = uniforms.srcX;
+ RIuint32 dstX = uniforms.dstX;
+ for (RIuint32 i = 0; i < uniforms.width; i++)
+ {
+ RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX);
+ IntegerColor ic = IntegerColor(c, state.srcDesc);
+ ic.expandColor(state.srcDesc);
+ ic.truncateColor(state.dstDesc);
+ RIuint32 dc = ic.getPackedColor(state.dstDesc);
+ Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
+
+ srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
+ dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
+
+ srcX++;
+ dstX++;
+ }
+ srcPtr = (void*)(srcStart + uniforms.srcStride);
+ dstPtr = (void*)(dstStart + uniforms.dstStride);
+ }
+ }
+ } else
+#endif
+ {
+ /* This block should handle the rest (and all) of the color-conversion cases. */
+ for (RIuint32 j = 0; j < uniforms.height; j++)
+ {
+ RIuint8* srcStart = (RIuint8*)srcPtr;
+ RIuint8* dstStart = (RIuint8*)dstPtr;
+ RIuint32 srcX = uniforms.srcX;
+ RIuint32 dstX = uniforms.dstX;
+ for (RIuint32 i = 0; i < uniforms.width; i++)
+ {
+ RIuint32 c = Image::readPackedPixelFromAddress(srcPtr, state.srcDesc.bitsPerPixel, srcX);
+ IntegerColor ic;
+ RIuint32 dc;
+
+ if (!state.isMaskOperation)
+ {
+ ic = IntegerColor(c, state.srcDesc);
+ if (state.unsafeInput)
+ ic.clampToAlpha();
+
+ ic.convertToFrom(state.dstDesc, state.srcDesc, false);
+ dc = ic.getPackedColor(state.dstDesc);
+ }
+ else
+ {
+ // Apply the given mask operation between two surfaces.
+ IntegerColor id;
+
+ if (maskOperationRequiresLoad(state.maskOperation))
+ {
+ ic.fromPackedMask(c, state.srcDesc);
+ ic.expandMask(state.srcDesc);
+
+ IntegerColor id;
+
+ RIuint32 d = Image::readPackedPixelFromAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX);
+ id.fromPackedMask(d, state.dstDesc);
+ id.expandColor(state.dstDesc);
+
+ RIuint32 coverage = ic.a + (ic.a >> 7);
+ ic = intMaskOperation(coverage, id, state.maskOperation);
+ }
+ else
+ {
+ // Other ops handled with memset, not blitter
+ RI_ASSERT(state.maskOperation == VG_SET_MASK);
+ ic.fromPackedMask(c, state.srcDesc);
+ //ic.expandMask(state.srcDesc);
+ ic.convertToFrom(state.dstDesc, state.srcDesc, true);
+ }
+ dc = ic.getPackedMaskColor(state.dstDesc);
+ }
+
+ Image::writePackedPixelToAddress(dstPtr, state.dstDesc.bitsPerPixel, dstX, dc);
+
+ srcPtr = Image::incrementPointer(srcPtr, state.srcDesc.bitsPerPixel, srcX);
+ dstPtr = (void*)Image::incrementPointer(dstPtr, state.dstDesc.bitsPerPixel, dstX);
+
+ srcX++;
+ dstX++;
+ }
+ srcPtr = (void*)(srcStart + uniforms.srcStride);
+ dstPtr = (void*)(dstStart + uniforms.dstStride);
+ }
+ }
+}
+
+}
+