Author: eliot
Date: 2011-08-08 12:01:31 -0700 (Mon, 08 Aug 2011)
New Revision: 2486
Modified:
branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c
branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
branches/Cog/unixbuild/mtbld/mvm
Log:
Include the rule 41 code in the BitBltPlugin. Fix regression in linux mt build
mvm script.
Modified: branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c
===================================================================
--- branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c 2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c 2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,9 +1,9 @@
/* Automatically generated by
- VMPluginCodeGenerator VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463
+ VMPluginCodeGenerator VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
from
- BitBltSimulation VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463
+ BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
*/
-static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463 " __DATE__ ;
+static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e " __DATE__ ;
@@ -67,7 +67,7 @@
#define FormHeightIndex 2
#define FormWidthIndex 1
#define GreenIndex 1
-#define OpTableSize 42
+#define OpTableSize 43
#define RedIndex 0
@@ -149,6 +149,7 @@
static sqInt partitionedMaxwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt partitionedMinwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt partitionedMulwithnBitsnPartitions(sqInt word1, sqInt word2, sqInt nBits, sqInt nParts);
+static sqInt partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts);
static sqInt partitionedSubfromnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt performCopyLoop(void);
static sqInt pickSourcePixelsflagssrcMaskdestMasksrcShiftIncdstShiftInc(sqInt nPixels, sqInt mapperFlags, sqInt srcMask, sqInt dstMask, sqInt srcShiftInc, sqInt dstShiftInc);
@@ -164,6 +165,11 @@
static sqInt queryDestSurface(sqInt handle);
static sqInt querySourceSurface(sqInt handle);
static sqInt rgbAddwith(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha16(void);
+static sqInt rgbComponentAlpha32(void);
+static sqInt rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha8(void);
+static sqInt rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord);
static sqInt rgbDiffwith(sqInt sourceWord, sqInt destinationWord);
static sqInt rgbMap16To32(sqInt sourcePixel);
static sqInt rgbMap32To32(sqInt sourcePixel);
@@ -214,6 +220,8 @@
static unsigned int * cmMaskTable;
static int * cmShiftTable;
static sqInt combinationRule;
+static sqInt componentAlphaModeAlpha;
+static sqInt componentAlphaModeColor;
static sqInt destBits;
static sqInt destDelta;
static sqInt destDepth;
@@ -242,6 +250,7 @@
static sqInt dstBitShift;
static sqInt dx;
static sqInt dy;
+static unsigned char * gammaLookupTable;
static sqInt halftoneBase;
static sqInt halftoneForm;
static sqInt halftoneHeight;
@@ -263,15 +272,15 @@
};
static const char *moduleName =
#ifdef SQUEAK_BUILTIN_PLUGIN
- "BitBltPlugin VMMaker.oscog-eem.105 (i)"
+ "BitBltPlugin VMMaker.oscog-eem.115 (i)"
#else
- "BitBltPlugin VMMaker.oscog-eem.105 (e)"
+ "BitBltPlugin VMMaker.oscog-eem.115 (e)"
#endif
;
static sqInt noHalftone;
static sqInt noSource;
static sqInt nWords;
-static void *opTable[42];
+static void *opTable[43];
static sqInt preload;
static void * querySurfaceFn;
static sqInt skew;
@@ -291,6 +300,7 @@
static sqInt srcBitShift;
static sqInt sx;
static sqInt sy;
+static unsigned char * ungammaLookupTable;
static void * unlockSurfaceFn;
static sqInt vDir;
static sqInt warpAlignMask;
@@ -1123,11 +1133,13 @@
sqInt dWid;
sqInt dxLowBits;
sqInt endBits;
+ sqInt gammaLookupTableOop;
sqInt pixPerM1;
sqInt pixPerM11;
sqInt startBits;
sqInt sxLowBits;
sqInt t;
+ sqInt ungammaLookupTableOop;
clipRange();
if ((bbW <= 0)
@@ -1142,12 +1154,58 @@
return interpreterProxy->primitiveFail();
}
/* begin copyBitsLockedAndClipped */
+ if (combinationRule == 41) {
+
+ /* Try a shortcut for stuff that should be run as quickly as possible */
+ /* fetch the forecolor into componentAlphaModeColor. */
+
+ componentAlphaModeAlpha = 255;
+ componentAlphaModeColor = 16777215;
+ gammaLookupTable = null;
+ ungammaLookupTable = null;
+ if ((interpreterProxy->methodArgumentCount()) >= 2) {
+ componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ if ((interpreterProxy->methodArgumentCount()) == 4) {
+ gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+ if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+ gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+ }
+ ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+ ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+ }
+ }
+ }
+ else {
+ if ((interpreterProxy->methodArgumentCount()) == 1) {
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ }
+ else {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ }
+ }
/* begin tryCopyingBitsQuickly */
if (noSource) {
done = 0;
goto l2;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
done = 0;
goto l2;
}
@@ -1159,6 +1217,37 @@
done = 0;
goto l2;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ done = 0;
+ goto l2;
+ }
if (destDepth < 8) {
done = 0;
goto l2;
@@ -1391,18 +1480,62 @@
sqInt dWid;
sqInt dxLowBits;
sqInt endBits;
+ sqInt gammaLookupTableOop;
sqInt pixPerM1;
sqInt pixPerM11;
sqInt startBits;
sqInt sxLowBits;
sqInt t;
+ sqInt ungammaLookupTableOop;
+ if (combinationRule == 41) {
+
+ /* Try a shortcut for stuff that should be run as quickly as possible */
+ /* fetch the forecolor into componentAlphaModeColor. */
+
+ componentAlphaModeAlpha = 255;
+ componentAlphaModeColor = 16777215;
+ gammaLookupTable = null;
+ ungammaLookupTable = null;
+ if ((interpreterProxy->methodArgumentCount()) >= 2) {
+ componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((interpreterProxy->methodArgumentCount()) == 4) {
+ gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+ if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+ gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+ }
+ ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+ ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+ }
+ }
+ }
+ else {
+ if ((interpreterProxy->methodArgumentCount()) == 1) {
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ else {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ }
/* begin tryCopyingBitsQuickly */
if (noSource) {
done = 0;
goto l1;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
done = 0;
goto l1;
}
@@ -1414,6 +1547,37 @@
done = 0;
goto l1;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ done = 0;
+ goto l1;
+ }
if (destDepth < 8) {
done = 0;
goto l1;
@@ -2643,6 +2807,7 @@
opTable[38+1] = (void *)pixSwapwith;
opTable[39+1] = (void *)pixClearwith;
opTable[40+1] = (void *)fixAlphawith;
+ opTable[41+1] = (void *)rgbComponentAlphawith;
}
static sqInt
@@ -2901,7 +3066,7 @@
}
ok = 1;
l3: /* end loadBitBltDestForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
destX = fetchIntOrFloatofObjectifNil(BBDestXIndex, bitBltOop, 0);
@@ -2982,7 +3147,7 @@
}
ok = 1;
l10: /* end loadBitBltSourceForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
/* begin loadColorMap */
@@ -3102,7 +3267,7 @@
}
ok = 1;
l4: /* end loadColorMap */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
if ((cmFlags & ColorMapNewStyle) == 0) {
@@ -3140,7 +3305,7 @@
halftoneBase = oopForPointer(interpreterProxy->firstIndexableField(halftoneBits));
ok = 1;
l5: /* end loadHalftoneForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
clipX = fetchIntOrFloatofObjectifNil(BBClipXIndex, bitBltOop, 0);
@@ -4047,7 +4212,101 @@
return result;
}
+static sqInt
+partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts)
+{
+ sqInt d;
+ sqInt destPix;
+ sqInt i;
+ sqInt mask;
+ sqInt mask3;
+ sqInt p1;
+ sqInt p2;
+ sqInt result;
+ sqInt srcPix;
+ sqInt v;
+
+ /* partition mask starts at the right */
+
+ mask = maskTable[nBits];
+ result = 0;
+ for (i = 1; i <= nParts; i += 1) {
+ p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * nBits);
+ p2 = ((usqInt) (destWord & mask)) >> ((i - 1) * nBits);
+ if (!(nBits == 32)) {
+ if (nBits == 16) {
+ p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+ p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+ }
+ else {
+ p1 = (rgbMapfromto(p1, nBits, 32)) | 4278190080UL;
+ p2 = (rgbMapfromto(p2, nBits, 32)) | 4278190080UL;
+ }
+ }
+ v = rgbComponentAlpha32with(p1, p2);
+ if (!(nBits == 32)) {
+ /* begin rgbMap:from:to: */
+ if (((d = nBits - 32)) > 0) {
+
+ /* Expand to more bits by zero-fill */
+ /* Transfer mask */
+
+ mask3 = (1 << 32) - 1;
+ srcPix = v << d;
+ mask3 = mask3 << d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << nBits;
+ srcPix = srcPix << d;
+ v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << nBits));
+ goto l1;
+ }
+ else {
+ if (d == 0) {
+ if (32 == 5) {
+ v = v & 32767;
+ goto l1;
+ }
+ if (32 == 8) {
+ v = v & 16777215;
+ goto l1;
+ }
+ v = v;
+ goto l1;
+ }
+ if (v == 0) {
+ v = v;
+ goto l1;
+ }
+ d = 32 - nBits;
+
+ /* Transfer mask */
+
+ mask3 = (1 << nBits) - 1;
+ srcPix = ((usqInt) v) >> d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << nBits;
+ srcPix = ((usqInt) srcPix) >> d;
+ destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << nBits));
+ if (destPix == 0) {
+ v = 1;
+ goto l1;
+ }
+ v = destPix;
+ goto l1;
+ }
+ l1: /* end rgbMap:from:to: */;
+ }
+ result = result | (v << ((i - 1) * nBits));
+
+ /* slide left to next partition */
+
+ mask = mask << nBits;
+ }
+ return result;
+}
+
+
/* Subtract word1 from word2 as nParts partitions of nBits each.
This is useful for packed pixels, or packed colors */
/* In C, most arithmetic operations answer the same bit pattern regardless of
@@ -4996,6 +5255,586 @@
}
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = 32
+ destPixSize = 16
+ sourceForm ~= destForm.
+ */
+/* This particular method should be optimized in itself */
+
+static sqInt
+rgbComponentAlpha16(void)
+{
+ sqInt addThreshold;
+ sqInt deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ sqInt ditherBase;
+ sqInt ditherIndex;
+ sqInt ditherThreshold;
+ sqInt dstIndex;
+ sqInt dstMask;
+ sqInt dstValue;
+ sqInt dstY;
+ sqInt sourceWord;
+ sqInt srcAlpha;
+ sqInt srcIndex;
+ sqInt srcShift;
+ sqInt srcY;
+
+
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+ dstY = dy;
+ srcShift = (dx & 1) * 16;
+ if (destMSB) {
+ srcShift = 16 - srcShift;
+ }
+
+ /* This is the outer loop */
+
+ mask1 = 65535 << (16 - srcShift);
+ while (((deltaY -= 1)) != 0) {
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 1)) * 4);
+ ditherBase = (dstY & 3) * 4;
+
+ /* For pre-increment */
+
+ ditherIndex = (sx & 3) - 1;
+
+ /* So we can pre-decrement */
+
+ deltaX = bbW + 1;
+ dstMask = mask1;
+ if (dstMask == 65535) {
+ srcShift = 16;
+ }
+ else {
+ srcShift = 0;
+ }
+ while (((deltaX -= 1)) != 0) {
+ ditherThreshold = ditherMatrix4x4[ditherBase + ((ditherIndex = (ditherIndex + 1) & 3))];
+ sourceWord = long32At(srcIndex);
+ srcAlpha = sourceWord & 16777215;
+ if (!(srcAlpha == 0)) {
+
+ /* 0 < srcAlpha */
+ /* If we have to mix colors then just copy a single word */
+
+ destWord = long32At(dstIndex);
+ destWord = destWord & (~dstMask);
+
+ /* Expand from 16 to 32 bit by adding zero bits */
+
+ destWord = ((usqInt) destWord) >> srcShift;
+
+ /* Mix colors */
+
+ destWord = ((((usqInt) (destWord & 31744) << 9)) | (((usqInt) (destWord & 992) << 6))) | ((((usqInt) (destWord & 31) << 3)) | 4278190080UL);
+
+ /* And dither */
+
+ sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+ /* begin dither32To16:threshold: */
+
+ /* You bet */
+
+ addThreshold = ((usqInt) ditherThreshold << 8);
+ sourceWord = ((((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 16)) & 255)]) << 10)) + (((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 8)) & 255)]) << 5))) + (dither8Lookup[addThreshold + (sourceWord & 255)]);
+ if (sourceWord == 0) {
+ sourceWord = 1 << srcShift;
+ }
+ else {
+ sourceWord = sourceWord << srcShift;
+ }
+ /* begin dstLongAt:put:mask: */
+ dstValue = long32At(dstIndex);
+ dstValue = dstValue & dstMask;
+ dstValue = dstValue | sourceWord;
+ long32Atput(dstIndex, dstValue);
+ }
+ srcIndex += 4;
+ if (destMSB) {
+ if (srcShift == 0) {
+ dstIndex += 4;
+ }
+ }
+ else {
+ if (!(srcShift == 0)) {
+ dstIndex += 4;
+ }
+ }
+
+ /* Toggle between 0 and 16 */
+
+ srcShift = srcShift ^ 16;
+ dstMask = ~dstMask;
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = destPixSize = 32
+ sourceForm ~= destForm.
+ Note: The inner loop has been optimized for dealing
+ with the special case of aR = aG = aB = 0
+ */
+
+static sqInt
+rgbComponentAlpha32(void)
+{
+ register int deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ register int dstIndex;
+ sqInt dstY;
+ register int sourceWord;
+ sqInt srcAlpha;
+ register int srcIndex;
+ sqInt srcY;
+
+
+ /* This particular method should be optimized in itself */
+ /* Give the compile a couple of hints */
+ /* The following should be declared as pointers so the compiler will
+ notice that they're used for accessing memory locations
+ (good to know on an Intel architecture) but then the increments
+ would be different between ST code and C code so must hope the
+ compiler notices what happens (MS Visual C does) */
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+
+ /* This is the outer loop */
+
+ dstY = dy;
+ while (((deltaY -= 1)) != 0) {
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + (dx * 4);
+
+ /* So we can pre-decrement */
+ /* This is the inner loop */
+
+ deltaX = bbW + 1;
+ while (((deltaX -= 1)) != 0) {
+ sourceWord = long32At(srcIndex);
+ srcAlpha = sourceWord & 16777215;
+ if (srcAlpha == 0) {
+ srcIndex += 4;
+
+ /* Now skip as many words as possible, */
+
+ dstIndex += 4;
+ while ((((deltaX -= 1)) != 0)
+ && ((((sourceWord = long32At(srcIndex))) & 16777215) == 0)) {
+ srcIndex += 4;
+ dstIndex += 4;
+ }
+ deltaX += 1;
+ }
+ else {
+
+ /* 0 < srcAlpha */
+ /* If we have to mix colors then just copy a single word */
+
+ destWord = long32At(dstIndex);
+ destWord = rgbComponentAlpha32with(sourceWord, destWord);
+ long32Atput(dstIndex, destWord);
+ srcIndex += 4;
+ dstIndex += 4;
+ }
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/*
+ componentAlphaModeColor is the color,
+ sourceWord contains an alpha value for each component of RGB
+ each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+ the rule is...
+
+ color = componentAlphaModeColor.
+ colorAlpha = componentAlphaModeAlpha.
+ mask = sourceWord.
+ dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+ dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+ dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+ dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+ dst.B */
+/* Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord)
+{
+ sqInt a;
+ sqInt aA;
+ sqInt aB;
+ sqInt aG;
+ sqInt alpha;
+ sqInt answer;
+ sqInt aR;
+ sqInt b;
+ sqInt d;
+ sqInt dstMask;
+ sqInt g;
+ sqInt r;
+ sqInt s;
+ sqInt srcAlpha;
+ sqInt srcColor;
+
+ alpha = sourceWord;
+ if (alpha == 0) {
+ return destinationWord;
+ }
+ srcColor = componentAlphaModeColor;
+ srcAlpha = componentAlphaModeAlpha & 255;
+ aB = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aG = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aR = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aA = alpha & 255;
+ if (!(srcAlpha == 255)) {
+ aA = ((usqInt) (aA * srcAlpha)) >> 8;
+ aR = ((usqInt) (aR * srcAlpha)) >> 8;
+ aG = ((usqInt) (aG * srcAlpha)) >> 8;
+ aB = ((usqInt) (aB * srcAlpha)) >> 8;
+ }
+ dstMask = destinationWord;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ b = (((usqInt) (d * (255 - aB))) >> 8) + (((usqInt) (s * aB)) >> 8);
+ if (b > 255) {
+ b = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ b = gammaLookupTable[b];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ g = (((usqInt) (d * (255 - aG))) >> 8) + (((usqInt) (s * aG)) >> 8);
+ if (g > 255) {
+ g = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ g = gammaLookupTable[g];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ r = (((usqInt) (d * (255 - aR))) >> 8) + (((usqInt) (s * aR)) >> 8);
+ if (r > 255) {
+ r = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ r = gammaLookupTable[r];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+
+ /* no need to gamma correct alpha value ? */
+
+ a = (((usqInt) ((dstMask & 255) * (255 - aA))) >> 8) + aA;
+ if (a > 255) {
+ a = 255;
+ }
+ answer = (((((a << 8) + r) << 8) + g) << 8) + b;
+ return answer;
+}
+
+
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = 32
+ destPixSize = 8
+ sourceForm ~= destForm.
+ Note: This is not real blending since we don't have the source colors
+ available. */
+
+static sqInt
+rgbComponentAlpha8(void)
+{
+ sqInt adjust;
+ sqInt deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ sqInt dstIndex;
+ sqInt dstMask;
+ sqInt dstValue;
+ sqInt dstY;
+ sqInt mapperFlags;
+ unsigned int *mappingTable;
+ sqInt pv;
+ sqInt sourceWord;
+ sqInt srcAlpha;
+ sqInt srcIndex;
+ sqInt srcShift;
+ sqInt srcY;
+ sqInt val;
+
+
+ /* This particular method should be optimized in itself */
+
+ mappingTable = default8To32Table();
+ mapperFlags = cmFlags & (~ColorMapNewStyle);
+
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+ dstY = dy;
+ mask1 = (dx & 3) * 8;
+ if (destMSB) {
+ mask1 = 24 - mask1;
+ }
+ mask2 = AllOnes ^ (255 << mask1);
+ if ((dx & 1) == 0) {
+ adjust = 0;
+ }
+ else {
+ adjust = 522133279;
+ }
+ if ((dy & 1) == 0) {
+ adjust = adjust ^ 522133279;
+ }
+ while (((deltaY -= 1)) != 0) {
+ adjust = adjust ^ 522133279;
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 2)) * 4);
+
+ /* So we can pre-decrement */
+
+ deltaX = bbW + 1;
+ srcShift = mask1;
+
+ /* This is the inner loop */
+
+ dstMask = mask2;
+ while (((deltaX -= 1)) != 0) {
+ sourceWord = ((long32At(srcIndex)) & (~adjust)) + adjust;
+
+ /* set srcAlpha to the average of the 3 separate aR,Ag,AB values */
+
+ srcAlpha = sourceWord & 16777215;
+ srcAlpha = (((((usqInt) srcAlpha) >> 16) + ((((usqInt) srcAlpha) >> 8) & 255)) + (srcAlpha & 255)) / 3;
+ if (srcAlpha > 31) {
+ if (srcAlpha > 224) {
+
+ /* Everything below 31 is transparent */
+ /* treat everything above 224 as opaque */
+
+ sourceWord = 4294967295UL;
+ }
+ destWord = long32At(dstIndex);
+ destWord = destWord & (~dstMask);
+ destWord = ((usqInt) destWord) >> srcShift;
+ destWord = mappingTable[destWord];
+ sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+ /* begin mapPixel:flags: */
+ pv = sourceWord;
+ if ((mapperFlags & ColorMapPresent) != 0) {
+ if ((mapperFlags & ColorMapFixedPart) != 0) {
+ /* begin rgbMapPixel:flags: */
+ val = (((cmShiftTable[0]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[0])) >> -(cmShiftTable[0])) : ((usqInt) (sourceWord & (cmMaskTable[0])) << (cmShiftTable[0])));
+ val = val | ((((cmShiftTable[1]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[1])) >> -(cmShiftTable[1])) : ((usqInt) (sourceWord & (cmMaskTable[1])) << (cmShiftTable[1]))));
+ val = val | ((((cmShiftTable[2]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[2])) >> -(cmShiftTable[2])) : ((usqInt) (sourceWord & (cmMaskTable[2])) << (cmShiftTable[2]))));
+ pv = val | ((((cmShiftTable[3]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[3])) >> -(cmShiftTable[3])) : ((usqInt) (sourceWord & (cmMaskTable[3])) << (cmShiftTable[3]))));
+ if ((pv == 0)
+ && (sourceWord != 0)) {
+ pv = 1;
+ }
+ }
+ if ((mapperFlags & ColorMapIndexedPart) != 0) {
+ pv = cmLookupTable[pv & cmMask];
+ }
+ }
+ sourceWord = pv;
+
+ /* Store back */
+
+ sourceWord = sourceWord << srcShift;
+ /* begin dstLongAt:put:mask: */
+ dstValue = long32At(dstIndex);
+ dstValue = dstValue & dstMask;
+ dstValue = dstValue | sourceWord;
+ long32Atput(dstIndex, dstValue);
+ }
+ srcIndex += 4;
+ if (destMSB) {
+ if (srcShift == 0) {
+ dstIndex += 4;
+ srcShift = 24;
+ dstMask = 16777215;
+ }
+ else {
+ srcShift -= 8;
+ dstMask = (((usqInt) dstMask) >> 8) | 4278190080UL;
+ }
+ }
+ else {
+ if (srcShift == 32) {
+ dstIndex += 4;
+ srcShift = 0;
+ dstMask = 4294967040UL;
+ }
+ else {
+ srcShift += 8;
+ dstMask = (dstMask << 8) | 255;
+ }
+ }
+ adjust = adjust ^ 522133279;
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/*
+ componentAlphaModeColor is the color,
+ sourceWord contains an alpha value for each component of RGB
+ each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+ the rule is...
+
+ color = componentAlphaModeColor.
+ colorAlpha = componentAlphaModeAlpha.
+ mask = sourceWord.
+ dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+ dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+ dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+ dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+ dst.B */
+/* Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord)
+{
+ sqInt alpha;
+ sqInt d;
+ sqInt destPix;
+ sqInt i;
+ sqInt mask;
+ sqInt mask3;
+ sqInt p1;
+ sqInt p2;
+ sqInt result;
+ sqInt srcPix;
+ sqInt v;
+
+ alpha = sourceWord;
+ if (alpha == 0) {
+ return destinationWord;
+ }
+ /* begin partitionedRgbComponentAlpha:dest:nBits:nPartitions: */
+
+ /* partition mask starts at the right */
+
+ mask = maskTable[destDepth];
+ result = 0;
+ for (i = 1; i <= destPPW; i += 1) {
+ p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * destDepth);
+ p2 = ((usqInt) (destinationWord & mask)) >> ((i - 1) * destDepth);
+ if (!(destDepth == 32)) {
+ if (destDepth == 16) {
+ p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+ p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+ }
+ else {
+ p1 = (rgbMapfromto(p1, destDepth, 32)) | 4278190080UL;
+ p2 = (rgbMapfromto(p2, destDepth, 32)) | 4278190080UL;
+ }
+ }
+ v = rgbComponentAlpha32with(p1, p2);
+ if (!(destDepth == 32)) {
+ /* begin rgbMap:from:to: */
+ if (((d = destDepth - 32)) > 0) {
+
+ /* Expand to more bits by zero-fill */
+ /* Transfer mask */
+
+ mask3 = (1 << 32) - 1;
+ srcPix = v << d;
+ mask3 = mask3 << d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << destDepth;
+ srcPix = srcPix << d;
+ v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << destDepth));
+ goto l1;
+ }
+ else {
+ if (d == 0) {
+ if (32 == 5) {
+ v = v & 32767;
+ goto l1;
+ }
+ if (32 == 8) {
+ v = v & 16777215;
+ goto l1;
+ }
+ v = v;
+ goto l1;
+ }
+ if (v == 0) {
+ v = v;
+ goto l1;
+ }
+ d = 32 - destDepth;
+
+ /* Transfer mask */
+
+ mask3 = (1 << destDepth) - 1;
+ srcPix = ((usqInt) v) >> d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << destDepth;
+ srcPix = ((usqInt) srcPix) >> d;
+ destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << destDepth));
+ if (destPix == 0) {
+ v = 1;
+ goto l1;
+ }
+ v = destPix;
+ goto l1;
+ }
+ l1: /* end rgbMap:from:to: */;
+ }
+ result = result | (v << ((i - 1) * destDepth));
+
+ /* slide left to next partition */
+
+ mask = mask << destDepth;
+ }
+ return result;
+}
+
+
/* Subract the pixels in the source and destination, color by color,
and return the sum of the absolute value of all the differences.
For non-rgb, return the number of differing pixels. */
@@ -5682,7 +6521,8 @@
if (noSource) {
return 0;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
return 0;
}
if (!(sourceDepth == 32)) {
@@ -5691,6 +6531,33 @@
if (sourceForm == destForm) {
return 0;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ return 0;
+ }
if (destDepth < 8) {
return 0;
}
@@ -5748,7 +6615,7 @@
destBits = (destPitch = 0);
destLocked = 1;
}
- if (!(noSource)) {
+ if (!noSource) {
sourceHandle = interpreterProxy->fetchPointerofObject(FormBitsIndex, sourceForm);
if ((sourceHandle & 1)) {
Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
- Sun Aug 7 13:36:19 PDT 2011
+ Mon Aug 8 12:00:18 PDT 2011
Modified: branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
===================================================================
--- branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c 2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c 2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,9 +1,9 @@
/* Automatically generated by
- VMPluginCodeGenerator VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99
+ VMPluginCodeGenerator VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
from
- BitBltSimulation VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99
+ BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
*/
-static char __buildInfo[] = "BitBltSimulation VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99 " __DATE__ ;
+static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e " __DATE__ ;
@@ -67,7 +67,7 @@
#define FormHeightIndex 2
#define FormWidthIndex 1
#define GreenIndex 1
-#define OpTableSize 42
+#define OpTableSize 43
#define RedIndex 0
@@ -149,6 +149,7 @@
static sqInt partitionedMaxwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt partitionedMinwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt partitionedMulwithnBitsnPartitions(sqInt word1, sqInt word2, sqInt nBits, sqInt nParts);
+static sqInt partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts);
static sqInt partitionedSubfromnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
static sqInt performCopyLoop(void);
static sqInt pickSourcePixelsflagssrcMaskdestMasksrcShiftIncdstShiftInc(sqInt nPixels, sqInt mapperFlags, sqInt srcMask, sqInt dstMask, sqInt srcShiftInc, sqInt dstShiftInc);
@@ -164,6 +165,11 @@
static sqInt queryDestSurface(sqInt handle);
static sqInt querySourceSurface(sqInt handle);
static sqInt rgbAddwith(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha16(void);
+static sqInt rgbComponentAlpha32(void);
+static sqInt rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha8(void);
+static sqInt rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord);
static sqInt rgbDiffwith(sqInt sourceWord, sqInt destinationWord);
static sqInt rgbMap16To32(sqInt sourcePixel);
static sqInt rgbMap32To32(sqInt sourcePixel);
@@ -214,6 +220,8 @@
static unsigned int * cmMaskTable;
static int * cmShiftTable;
static sqInt combinationRule;
+static sqInt componentAlphaModeAlpha;
+static sqInt componentAlphaModeColor;
static sqInt destBits;
static sqInt destDelta;
static sqInt destDepth;
@@ -242,6 +250,7 @@
static sqInt dstBitShift;
static sqInt dx;
static sqInt dy;
+static unsigned char * gammaLookupTable;
static sqInt halftoneBase;
static sqInt halftoneForm;
static sqInt halftoneHeight;
@@ -263,15 +272,15 @@
};
static const char *moduleName =
#ifdef SQUEAK_BUILTIN_PLUGIN
- "BitBltPlugin VMMaker-oscog.40 (i)"
+ "BitBltPlugin VMMaker.oscog-eem.115 (i)"
#else
- "BitBltPlugin VMMaker-oscog.40 (e)"
+ "BitBltPlugin VMMaker.oscog-eem.115 (e)"
#endif
;
static sqInt noHalftone;
static sqInt noSource;
static sqInt nWords;
-static void *opTable[42];
+static void *opTable[43];
static sqInt preload;
static void * querySurfaceFn;
static sqInt skew;
@@ -291,6 +300,7 @@
static sqInt srcBitShift;
static sqInt sx;
static sqInt sy;
+static unsigned char * ungammaLookupTable;
static void * unlockSurfaceFn;
static sqInt vDir;
static sqInt warpAlignMask;
@@ -755,7 +765,7 @@
dstIndex += 4;
while ((((deltaX -= 1)) != 0)
- && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 255)) {
+ && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 255)) {
long32Atput(dstIndex, sourceWord);
srcIndex += 4;
dstIndex += 4;
@@ -773,7 +783,7 @@
dstIndex += 4;
while ((((deltaX -= 1)) != 0)
- && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 0)) {
+ && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 0)) {
srcIndex += 4;
dstIndex += 4;
}
@@ -1123,11 +1133,13 @@
sqInt dWid;
sqInt dxLowBits;
sqInt endBits;
+ sqInt gammaLookupTableOop;
sqInt pixPerM1;
sqInt pixPerM11;
sqInt startBits;
sqInt sxLowBits;
sqInt t;
+ sqInt ungammaLookupTableOop;
clipRange();
if ((bbW <= 0)
@@ -1135,19 +1147,65 @@
/* zero width or height; noop */
- affectedL = affectedR = affectedT = affectedB = 0;
+ affectedL = (affectedR = (affectedT = (affectedB = 0)));
return null;
}
if (!(lockSurfaces())) {
return interpreterProxy->primitiveFail();
}
/* begin copyBitsLockedAndClipped */
+ if (combinationRule == 41) {
+
+ /* Try a shortcut for stuff that should be run as quickly as possible */
+ /* fetch the forecolor into componentAlphaModeColor. */
+
+ componentAlphaModeAlpha = 255;
+ componentAlphaModeColor = 16777215;
+ gammaLookupTable = null;
+ ungammaLookupTable = null;
+ if ((interpreterProxy->methodArgumentCount()) >= 2) {
+ componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ if ((interpreterProxy->methodArgumentCount()) == 4) {
+ gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+ if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+ gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+ }
+ ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+ ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+ }
+ }
+ }
+ else {
+ if ((interpreterProxy->methodArgumentCount()) == 1) {
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+ if (!(!(interpreterProxy->failed()))) {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ }
+ else {
+ interpreterProxy->primitiveFail();
+ goto l1;
+ }
+ }
+ }
/* begin tryCopyingBitsQuickly */
if (noSource) {
done = 0;
goto l2;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
done = 0;
goto l2;
}
@@ -1159,6 +1217,37 @@
done = 0;
goto l2;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l2;
+ }
+ done = 0;
+ goto l2;
+ }
if (destDepth < 8) {
done = 0;
goto l2;
@@ -1241,7 +1330,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
if (noSource) {
@@ -1285,7 +1374,7 @@
}
if ((sourceDepth != destDepth)
|| ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+ || (sourceMSB != destMSB))) {
copyLoopPixMap();
}
else {
@@ -1343,7 +1432,7 @@
/* zero width and height; return the count */
- affectedL = affectedR = affectedT = affectedB = 0;
+ affectedL = (affectedR = (affectedT = (affectedB = 0)));
}
if (hDir > 0) {
affectedL = dx;
@@ -1391,18 +1480,62 @@
sqInt dWid;
sqInt dxLowBits;
sqInt endBits;
+ sqInt gammaLookupTableOop;
sqInt pixPerM1;
sqInt pixPerM11;
sqInt startBits;
sqInt sxLowBits;
sqInt t;
+ sqInt ungammaLookupTableOop;
+ if (combinationRule == 41) {
+
+ /* Try a shortcut for stuff that should be run as quickly as possible */
+ /* fetch the forecolor into componentAlphaModeColor. */
+
+ componentAlphaModeAlpha = 255;
+ componentAlphaModeColor = 16777215;
+ gammaLookupTable = null;
+ ungammaLookupTable = null;
+ if ((interpreterProxy->methodArgumentCount()) >= 2) {
+ componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((interpreterProxy->methodArgumentCount()) == 4) {
+ gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+ if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+ gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+ }
+ ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+ ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+ }
+ }
+ }
+ else {
+ if ((interpreterProxy->methodArgumentCount()) == 1) {
+ componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+ if (!(!(interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ else {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ }
/* begin tryCopyingBitsQuickly */
if (noSource) {
done = 0;
goto l1;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
done = 0;
goto l1;
}
@@ -1414,6 +1547,37 @@
done = 0;
goto l1;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ done = 1;
+ goto l1;
+ }
+ done = 0;
+ goto l1;
+ }
if (destDepth < 8) {
done = 0;
goto l1;
@@ -1494,7 +1658,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
if (noSource) {
@@ -1538,7 +1702,7 @@
}
if ((sourceDepth != destDepth)
|| ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+ || (sourceMSB != destMSB))) {
copyLoopPixMap();
}
else {
@@ -1596,7 +1760,7 @@
/* zero width and height; return the count */
- affectedL = affectedR = affectedT = affectedB = 0;
+ affectedL = (affectedR = (affectedT = (affectedB = 0)));
}
if (hDir > 0) {
affectedL = dx;
@@ -1645,7 +1809,7 @@
hInc = hDir * 4;
if (skew == -32) {
- skew = unskew = skewMask = 0;
+ skew = (unskew = (skewMask = 0));
}
else {
if (skew < 0) {
@@ -2008,7 +2172,7 @@
srcShift1 -= 32;
}
/* begin srcLongAt: */
- idx = sourceIndex += 4;
+ idx = (sourceIndex += 4);
sourceWord = long32At(idx);
}
} while(!(((nPix1 -= 1)) == 0));
@@ -2054,7 +2218,7 @@
srcShift1 -= 32;
}
/* begin srcLongAt: */
- idx1 = sourceIndex += 4;
+ idx1 = (sourceIndex += 4);
sourceWord = long32At(idx1);
}
} while(!(((nPix1 -= 1)) == 0));
@@ -2225,7 +2389,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
}
@@ -2290,8 +2454,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
if (py > px) {
/* more horizontal */
@@ -2330,8 +2494,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
}
}
}
@@ -2375,8 +2539,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
}
}
}
@@ -2643,6 +2807,7 @@
opTable[38+1] = (void *)pixSwapwith;
opTable[39+1] = (void *)pixClearwith;
opTable[40+1] = (void *)fixAlphawith;
+ opTable[41+1] = (void *)rgbComponentAlphawith;
}
static sqInt
@@ -2715,12 +2880,12 @@
}
if (((shifts[RedIndex]) == 0)
&& (((shifts[GreenIndex]) == 0)
- && (((shifts[BlueIndex]) == 0)
- && (((shifts[AlphaIndex]) == 0)
- && (((masks[RedIndex]) == 16711680)
- && (((masks[GreenIndex]) == 65280)
- && (((masks[BlueIndex]) == 255)
- && ((masks[AlphaIndex]) == 4278190080UL)))))))) {
+ && (((shifts[BlueIndex]) == 0)
+ && (((shifts[AlphaIndex]) == 0)
+ && (((masks[RedIndex]) == 16711680)
+ && (((masks[GreenIndex]) == 65280)
+ && (((masks[BlueIndex]) == 255)
+ && ((masks[AlphaIndex]) == 4278190080UL)))))))) {
return 1;
}
return 0;
@@ -2753,7 +2918,7 @@
return 0;
}
destPPW = 32 / destDepth;
- destBits = destPitch = 0;
+ destBits = (destPitch = 0);
}
else {
destPPW = 32 / destDepth;
@@ -2806,7 +2971,7 @@
combinationRule = interpreterProxy->fetchIntegerofObject(BBRuleIndex, bitBltOop);
if ((interpreterProxy->failed())
|| ((combinationRule < 0)
- || (combinationRule > (OpTableSize - 2)))) {
+ || (combinationRule > (OpTableSize - 2)))) {
return 0;
}
if ((combinationRule >= 16)
@@ -2886,7 +3051,7 @@
goto l3;
}
destPPW = 32 / destDepth;
- destBits = destPitch = 0;
+ destBits = (destPitch = 0);
}
else {
destPPW = 32 / destDepth;
@@ -2901,7 +3066,7 @@
}
ok = 1;
l3: /* end loadBitBltDestForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
destX = fetchIntOrFloatofObjectifNil(BBDestXIndex, bitBltOop, 0);
@@ -2912,7 +3077,7 @@
return 0;
}
if (noSource) {
- sourceX = sourceY = 0;
+ sourceX = (sourceY = 0);
}
else {
if (!((interpreterProxy->isPointers(sourceForm))
@@ -2967,7 +3132,7 @@
goto l10;
}
sourcePPW = 32 / sourceDepth;
- sourceBits = sourcePitch = 0;
+ sourceBits = (sourcePitch = 0);
}
else {
sourcePPW = 32 / sourceDepth;
@@ -2982,11 +3147,11 @@
}
ok = 1;
l10: /* end loadBitBltSourceForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
/* begin loadColorMap */
- cmFlags = cmMask = cmBitsPerColor = 0;
+ cmFlags = (cmMask = (cmBitsPerColor = 0));
cmShiftTable = null;
cmMaskTable = null;
cmLookupTable = null;
@@ -3102,7 +3267,7 @@
}
ok = 1;
l4: /* end loadColorMap */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
if ((cmFlags & ColorMapNewStyle) == 0) {
@@ -3140,7 +3305,7 @@
halftoneBase = oopForPointer(interpreterProxy->firstIndexableField(halftoneBits));
ok = 1;
l5: /* end loadHalftoneForm */;
- if (!(ok)) {
+ if (!ok) {
return 0;
}
clipX = fetchIntOrFloatofObjectifNil(BBClipXIndex, bitBltOop, 0);
@@ -3226,7 +3391,7 @@
return 0;
}
sourcePPW = 32 / sourceDepth;
- sourceBits = sourcePitch = 0;
+ sourceBits = (sourcePitch = 0);
}
else {
sourcePPW = 32 / sourceDepth;
@@ -3256,7 +3421,7 @@
sqInt oldStyle;
sqInt oop;
- cmFlags = cmMask = cmBitsPerColor = 0;
+ cmFlags = (cmMask = (cmBitsPerColor = 0));
cmShiftTable = null;
cmMaskTable = null;
cmLookupTable = null;
@@ -3433,7 +3598,7 @@
unlockSurfaceFn = interpreterProxy->ioLoadFunctionFrom("ioUnlockSurface", "SurfacePlugin");
return (querySurfaceFn != 0)
&& ((lockSurfaceFn != 0)
- && (unlockSurfaceFn != 0));
+ && (unlockSurfaceFn != 0));
}
static sqInt
@@ -3554,7 +3719,7 @@
}
return (destBits != 0)
&& ((sourceBits != 0)
- || (noSource));
+ || (noSource));
}
@@ -3607,7 +3772,7 @@
moduleUnloaded(char *aModuleName)
{
if ((strcmp(aModuleName, "SurfacePlugin")) == 0) {
- querySurfaceFn = lockSurfaceFn = unlockSurfaceFn = 0;
+ querySurfaceFn = (lockSurfaceFn = (unlockSurfaceFn = 0));
}
}
@@ -4047,7 +4212,101 @@
return result;
}
+static sqInt
+partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts)
+{
+ sqInt d;
+ sqInt destPix;
+ sqInt i;
+ sqInt mask;
+ sqInt mask3;
+ sqInt p1;
+ sqInt p2;
+ sqInt result;
+ sqInt srcPix;
+ sqInt v;
+
+ /* partition mask starts at the right */
+
+ mask = maskTable[nBits];
+ result = 0;
+ for (i = 1; i <= nParts; i += 1) {
+ p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * nBits);
+ p2 = ((usqInt) (destWord & mask)) >> ((i - 1) * nBits);
+ if (!(nBits == 32)) {
+ if (nBits == 16) {
+ p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+ p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+ }
+ else {
+ p1 = (rgbMapfromto(p1, nBits, 32)) | 4278190080UL;
+ p2 = (rgbMapfromto(p2, nBits, 32)) | 4278190080UL;
+ }
+ }
+ v = rgbComponentAlpha32with(p1, p2);
+ if (!(nBits == 32)) {
+ /* begin rgbMap:from:to: */
+ if (((d = nBits - 32)) > 0) {
+
+ /* Expand to more bits by zero-fill */
+ /* Transfer mask */
+
+ mask3 = (1 << 32) - 1;
+ srcPix = v << d;
+ mask3 = mask3 << d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << nBits;
+ srcPix = srcPix << d;
+ v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << nBits));
+ goto l1;
+ }
+ else {
+ if (d == 0) {
+ if (32 == 5) {
+ v = v & 32767;
+ goto l1;
+ }
+ if (32 == 8) {
+ v = v & 16777215;
+ goto l1;
+ }
+ v = v;
+ goto l1;
+ }
+ if (v == 0) {
+ v = v;
+ goto l1;
+ }
+ d = 32 - nBits;
+
+ /* Transfer mask */
+
+ mask3 = (1 << nBits) - 1;
+ srcPix = ((usqInt) v) >> d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << nBits;
+ srcPix = ((usqInt) srcPix) >> d;
+ destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << nBits));
+ if (destPix == 0) {
+ v = 1;
+ goto l1;
+ }
+ v = destPix;
+ goto l1;
+ }
+ l1: /* end rgbMap:from:to: */;
+ }
+ result = result | (v << ((i - 1) * nBits));
+
+ /* slide left to next partition */
+
+ mask = mask << nBits;
+ }
+ return result;
+}
+
+
/* Subtract word1 from word2 as nParts partitions of nBits each.
This is useful for packed pixels, or packed colors */
/* In C, most arithmetic operations answer the same bit pattern regardless of
@@ -4141,7 +4400,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
if (noSource) {
@@ -4185,7 +4444,7 @@
}
if ((sourceDepth != destDepth)
|| ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+ || (sourceMSB != destMSB))) {
copyLoopPixMap();
}
else {
@@ -4303,7 +4562,7 @@
srcShift -= 32;
}
/* begin srcLongAt: */
- idx = sourceIndex += 4;
+ idx = (sourceIndex += 4);
sourceWord = long32At(idx);
}
} while(!(((nPix -= 1)) == 0));
@@ -4349,7 +4608,7 @@
srcShift -= 32;
}
/* begin srcLongAt: */
- idx1 = sourceIndex += 4;
+ idx1 = (sourceIndex += 4);
sourceWord = long32At(idx1);
}
} while(!(((nPix -= 1)) == 0));
@@ -4377,8 +4636,8 @@
if ((xx < 0)
|| ((yy < 0)
- || ((((x = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
+ || (((y = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
return 0;
}
srcIndex = (sourceBits + (y * sourcePitch)) + ((((usqInt) x) >> warpAlignShift) * 4);
@@ -4581,7 +4840,7 @@
}
if (!((startIndex > 0)
&& ((stopIndex > 0)
- && (stopIndex <= (interpreterProxy->byteSizeOf(sourceString)))))) {
+ && (stopIndex <= (interpreterProxy->byteSizeOf(sourceString)))))) {
return interpreterProxy->primitiveFail();
}
bbObj = interpreterProxy->stackObjectValue(6);
@@ -4594,11 +4853,11 @@
}
quickBlt = (destBits != 0)
&& ((sourceBits != 0)
- && ((noSource == 0)
- && ((sourceForm != destForm)
- && ((cmFlags != 0)
- || ((sourceMSB != destMSB)
- || (sourceDepth != destDepth))))));
+ && ((noSource == 0)
+ && ((sourceForm != destForm)
+ && ((cmFlags != 0)
+ || ((sourceMSB != destMSB)
+ || (sourceDepth != destDepth))))));
left = destX;
sourcePtr = interpreterProxy->firstIndexableField(sourceString);
for (charIndex = startIndex; charIndex <= stopIndex; charIndex += 1) {
@@ -4650,7 +4909,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
copyLoopPixMap();
@@ -4729,8 +4988,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
if (py > px) {
/* more horizontal */
@@ -4769,8 +5028,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
}
}
}
@@ -4814,8 +5073,8 @@
/* init null rectangle */
- affL = affT = 9999;
- affR = affB = -9999;
+ affL = (affT = 9999);
+ affR = (affB = -9999);
}
}
}
@@ -4864,11 +5123,11 @@
noSource = ns;
if (noSource
|| ((bbW <= 0)
- || (bbH <= 0))) {
+ || (bbH <= 0))) {
/* zero width or height; noop */
- affectedL = affectedR = affectedT = affectedB = 0;
+ affectedL = (affectedR = (affectedT = (affectedB = 0)));
goto l1;
}
if (!(lockSurfaces())) {
@@ -4908,7 +5167,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
warpLoop();
@@ -4996,6 +5255,586 @@
}
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = 32
+ destPixSize = 16
+ sourceForm ~= destForm.
+ */
+/* This particular method should be optimized in itself */
+
+static sqInt
+rgbComponentAlpha16(void)
+{
+ sqInt addThreshold;
+ sqInt deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ sqInt ditherBase;
+ sqInt ditherIndex;
+ sqInt ditherThreshold;
+ sqInt dstIndex;
+ sqInt dstMask;
+ sqInt dstValue;
+ sqInt dstY;
+ sqInt sourceWord;
+ sqInt srcAlpha;
+ sqInt srcIndex;
+ sqInt srcShift;
+ sqInt srcY;
+
+
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+ dstY = dy;
+ srcShift = (dx & 1) * 16;
+ if (destMSB) {
+ srcShift = 16 - srcShift;
+ }
+
+ /* This is the outer loop */
+
+ mask1 = 65535 << (16 - srcShift);
+ while (((deltaY -= 1)) != 0) {
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 1)) * 4);
+ ditherBase = (dstY & 3) * 4;
+
+ /* For pre-increment */
+
+ ditherIndex = (sx & 3) - 1;
+
+ /* So we can pre-decrement */
+
+ deltaX = bbW + 1;
+ dstMask = mask1;
+ if (dstMask == 65535) {
+ srcShift = 16;
+ }
+ else {
+ srcShift = 0;
+ }
+ while (((deltaX -= 1)) != 0) {
+ ditherThreshold = ditherMatrix4x4[ditherBase + ((ditherIndex = (ditherIndex + 1) & 3))];
+ sourceWord = long32At(srcIndex);
+ srcAlpha = sourceWord & 16777215;
+ if (!(srcAlpha == 0)) {
+
+ /* 0 < srcAlpha */
+ /* If we have to mix colors then just copy a single word */
+
+ destWord = long32At(dstIndex);
+ destWord = destWord & (~dstMask);
+
+ /* Expand from 16 to 32 bit by adding zero bits */
+
+ destWord = ((usqInt) destWord) >> srcShift;
+
+ /* Mix colors */
+
+ destWord = ((((usqInt) (destWord & 31744) << 9)) | (((usqInt) (destWord & 992) << 6))) | ((((usqInt) (destWord & 31) << 3)) | 4278190080UL);
+
+ /* And dither */
+
+ sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+ /* begin dither32To16:threshold: */
+
+ /* You bet */
+
+ addThreshold = ((usqInt) ditherThreshold << 8);
+ sourceWord = ((((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 16)) & 255)]) << 10)) + (((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 8)) & 255)]) << 5))) + (dither8Lookup[addThreshold + (sourceWord & 255)]);
+ if (sourceWord == 0) {
+ sourceWord = 1 << srcShift;
+ }
+ else {
+ sourceWord = sourceWord << srcShift;
+ }
+ /* begin dstLongAt:put:mask: */
+ dstValue = long32At(dstIndex);
+ dstValue = dstValue & dstMask;
+ dstValue = dstValue | sourceWord;
+ long32Atput(dstIndex, dstValue);
+ }
+ srcIndex += 4;
+ if (destMSB) {
+ if (srcShift == 0) {
+ dstIndex += 4;
+ }
+ }
+ else {
+ if (!(srcShift == 0)) {
+ dstIndex += 4;
+ }
+ }
+
+ /* Toggle between 0 and 16 */
+
+ srcShift = srcShift ^ 16;
+ dstMask = ~dstMask;
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = destPixSize = 32
+ sourceForm ~= destForm.
+ Note: The inner loop has been optimized for dealing
+ with the special case of aR = aG = aB = 0
+ */
+
+static sqInt
+rgbComponentAlpha32(void)
+{
+ register int deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ register int dstIndex;
+ sqInt dstY;
+ register int sourceWord;
+ sqInt srcAlpha;
+ register int srcIndex;
+ sqInt srcY;
+
+
+ /* This particular method should be optimized in itself */
+ /* Give the compile a couple of hints */
+ /* The following should be declared as pointers so the compiler will
+ notice that they're used for accessing memory locations
+ (good to know on an Intel architecture) but then the increments
+ would be different between ST code and C code so must hope the
+ compiler notices what happens (MS Visual C does) */
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+
+ /* This is the outer loop */
+
+ dstY = dy;
+ while (((deltaY -= 1)) != 0) {
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + (dx * 4);
+
+ /* So we can pre-decrement */
+ /* This is the inner loop */
+
+ deltaX = bbW + 1;
+ while (((deltaX -= 1)) != 0) {
+ sourceWord = long32At(srcIndex);
+ srcAlpha = sourceWord & 16777215;
+ if (srcAlpha == 0) {
+ srcIndex += 4;
+
+ /* Now skip as many words as possible, */
+
+ dstIndex += 4;
+ while ((((deltaX -= 1)) != 0)
+ && ((((sourceWord = long32At(srcIndex))) & 16777215) == 0)) {
+ srcIndex += 4;
+ dstIndex += 4;
+ }
+ deltaX += 1;
+ }
+ else {
+
+ /* 0 < srcAlpha */
+ /* If we have to mix colors then just copy a single word */
+
+ destWord = long32At(dstIndex);
+ destWord = rgbComponentAlpha32with(sourceWord, destWord);
+ long32Atput(dstIndex, destWord);
+ srcIndex += 4;
+ dstIndex += 4;
+ }
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/*
+ componentAlphaModeColor is the color,
+ sourceWord contains an alpha value for each component of RGB
+ each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+ the rule is...
+
+ color = componentAlphaModeColor.
+ colorAlpha = componentAlphaModeAlpha.
+ mask = sourceWord.
+ dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+ dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+ dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+ dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+ dst.B */
+/* Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord)
+{
+ sqInt a;
+ sqInt aA;
+ sqInt aB;
+ sqInt aG;
+ sqInt alpha;
+ sqInt answer;
+ sqInt aR;
+ sqInt b;
+ sqInt d;
+ sqInt dstMask;
+ sqInt g;
+ sqInt r;
+ sqInt s;
+ sqInt srcAlpha;
+ sqInt srcColor;
+
+ alpha = sourceWord;
+ if (alpha == 0) {
+ return destinationWord;
+ }
+ srcColor = componentAlphaModeColor;
+ srcAlpha = componentAlphaModeAlpha & 255;
+ aB = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aG = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aR = alpha & 255;
+ alpha = ((usqInt) alpha) >> 8;
+ aA = alpha & 255;
+ if (!(srcAlpha == 255)) {
+ aA = ((usqInt) (aA * srcAlpha)) >> 8;
+ aR = ((usqInt) (aR * srcAlpha)) >> 8;
+ aG = ((usqInt) (aG * srcAlpha)) >> 8;
+ aB = ((usqInt) (aB * srcAlpha)) >> 8;
+ }
+ dstMask = destinationWord;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ b = (((usqInt) (d * (255 - aB))) >> 8) + (((usqInt) (s * aB)) >> 8);
+ if (b > 255) {
+ b = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ b = gammaLookupTable[b];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ g = (((usqInt) (d * (255 - aG))) >> 8) + (((usqInt) (s * aG)) >> 8);
+ if (g > 255) {
+ g = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ g = gammaLookupTable[g];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+ d = dstMask & 255;
+ s = srcColor & 255;
+ if (!(ungammaLookupTable == null)) {
+ d = ungammaLookupTable[d];
+ s = ungammaLookupTable[s];
+ }
+ r = (((usqInt) (d * (255 - aR))) >> 8) + (((usqInt) (s * aR)) >> 8);
+ if (r > 255) {
+ r = 255;
+ }
+ if (!(gammaLookupTable == null)) {
+ r = gammaLookupTable[r];
+ }
+ dstMask = ((usqInt) dstMask) >> 8;
+ srcColor = ((usqInt) srcColor) >> 8;
+
+ /* no need to gamma correct alpha value ? */
+
+ a = (((usqInt) ((dstMask & 255) * (255 - aA))) >> 8) + aA;
+ if (a > 255) {
+ a = 255;
+ }
+ answer = (((((a << 8) + r) << 8) + g) << 8) + b;
+ return answer;
+}
+
+
+/* This version assumes
+ combinationRule = 41
+ sourcePixSize = 32
+ destPixSize = 8
+ sourceForm ~= destForm.
+ Note: This is not real blending since we don't have the source colors
+ available. */
+
+static sqInt
+rgbComponentAlpha8(void)
+{
+ sqInt adjust;
+ sqInt deltaX;
+ sqInt deltaY;
+ sqInt destWord;
+ sqInt dstIndex;
+ sqInt dstMask;
+ sqInt dstValue;
+ sqInt dstY;
+ sqInt mapperFlags;
+ unsigned int *mappingTable;
+ sqInt pv;
+ sqInt sourceWord;
+ sqInt srcAlpha;
+ sqInt srcIndex;
+ sqInt srcShift;
+ sqInt srcY;
+ sqInt val;
+
+
+ /* This particular method should be optimized in itself */
+
+ mappingTable = default8To32Table();
+ mapperFlags = cmFlags & (~ColorMapNewStyle);
+
+ /* So we can pre-decrement */
+
+ deltaY = bbH + 1;
+ srcY = sy;
+ dstY = dy;
+ mask1 = (dx & 3) * 8;
+ if (destMSB) {
+ mask1 = 24 - mask1;
+ }
+ mask2 = AllOnes ^ (255 << mask1);
+ if ((dx & 1) == 0) {
+ adjust = 0;
+ }
+ else {
+ adjust = 522133279;
+ }
+ if ((dy & 1) == 0) {
+ adjust = adjust ^ 522133279;
+ }
+ while (((deltaY -= 1)) != 0) {
+ adjust = adjust ^ 522133279;
+ srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+ dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 2)) * 4);
+
+ /* So we can pre-decrement */
+
+ deltaX = bbW + 1;
+ srcShift = mask1;
+
+ /* This is the inner loop */
+
+ dstMask = mask2;
+ while (((deltaX -= 1)) != 0) {
+ sourceWord = ((long32At(srcIndex)) & (~adjust)) + adjust;
+
+ /* set srcAlpha to the average of the 3 separate aR,Ag,AB values */
+
+ srcAlpha = sourceWord & 16777215;
+ srcAlpha = (((((usqInt) srcAlpha) >> 16) + ((((usqInt) srcAlpha) >> 8) & 255)) + (srcAlpha & 255)) / 3;
+ if (srcAlpha > 31) {
+ if (srcAlpha > 224) {
+
+ /* Everything below 31 is transparent */
+ /* treat everything above 224 as opaque */
+
+ sourceWord = 4294967295UL;
+ }
+ destWord = long32At(dstIndex);
+ destWord = destWord & (~dstMask);
+ destWord = ((usqInt) destWord) >> srcShift;
+ destWord = mappingTable[destWord];
+ sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+ /* begin mapPixel:flags: */
+ pv = sourceWord;
+ if ((mapperFlags & ColorMapPresent) != 0) {
+ if ((mapperFlags & ColorMapFixedPart) != 0) {
+ /* begin rgbMapPixel:flags: */
+ val = (((cmShiftTable[0]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[0])) >> -(cmShiftTable[0])) : ((usqInt) (sourceWord & (cmMaskTable[0])) << (cmShiftTable[0])));
+ val = val | ((((cmShiftTable[1]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[1])) >> -(cmShiftTable[1])) : ((usqInt) (sourceWord & (cmMaskTable[1])) << (cmShiftTable[1]))));
+ val = val | ((((cmShiftTable[2]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[2])) >> -(cmShiftTable[2])) : ((usqInt) (sourceWord & (cmMaskTable[2])) << (cmShiftTable[2]))));
+ pv = val | ((((cmShiftTable[3]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[3])) >> -(cmShiftTable[3])) : ((usqInt) (sourceWord & (cmMaskTable[3])) << (cmShiftTable[3]))));
+ if ((pv == 0)
+ && (sourceWord != 0)) {
+ pv = 1;
+ }
+ }
+ if ((mapperFlags & ColorMapIndexedPart) != 0) {
+ pv = cmLookupTable[pv & cmMask];
+ }
+ }
+ sourceWord = pv;
+
+ /* Store back */
+
+ sourceWord = sourceWord << srcShift;
+ /* begin dstLongAt:put:mask: */
+ dstValue = long32At(dstIndex);
+ dstValue = dstValue & dstMask;
+ dstValue = dstValue | sourceWord;
+ long32Atput(dstIndex, dstValue);
+ }
+ srcIndex += 4;
+ if (destMSB) {
+ if (srcShift == 0) {
+ dstIndex += 4;
+ srcShift = 24;
+ dstMask = 16777215;
+ }
+ else {
+ srcShift -= 8;
+ dstMask = (((usqInt) dstMask) >> 8) | 4278190080UL;
+ }
+ }
+ else {
+ if (srcShift == 32) {
+ dstIndex += 4;
+ srcShift = 0;
+ dstMask = 4294967040UL;
+ }
+ else {
+ srcShift += 8;
+ dstMask = (dstMask << 8) | 255;
+ }
+ }
+ adjust = adjust ^ 522133279;
+ }
+ srcY += 1;
+ dstY += 1;
+ }
+}
+
+
+/*
+ componentAlphaModeColor is the color,
+ sourceWord contains an alpha value for each component of RGB
+ each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+ the rule is...
+
+ color = componentAlphaModeColor.
+ colorAlpha = componentAlphaModeAlpha.
+ mask = sourceWord.
+ dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+ dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+ dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+ dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+ dst.B */
+/* Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord)
+{
+ sqInt alpha;
+ sqInt d;
+ sqInt destPix;
+ sqInt i;
+ sqInt mask;
+ sqInt mask3;
+ sqInt p1;
+ sqInt p2;
+ sqInt result;
+ sqInt srcPix;
+ sqInt v;
+
+ alpha = sourceWord;
+ if (alpha == 0) {
+ return destinationWord;
+ }
+ /* begin partitionedRgbComponentAlpha:dest:nBits:nPartitions: */
+
+ /* partition mask starts at the right */
+
+ mask = maskTable[destDepth];
+ result = 0;
+ for (i = 1; i <= destPPW; i += 1) {
+ p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * destDepth);
+ p2 = ((usqInt) (destinationWord & mask)) >> ((i - 1) * destDepth);
+ if (!(destDepth == 32)) {
+ if (destDepth == 16) {
+ p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+ p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+ }
+ else {
+ p1 = (rgbMapfromto(p1, destDepth, 32)) | 4278190080UL;
+ p2 = (rgbMapfromto(p2, destDepth, 32)) | 4278190080UL;
+ }
+ }
+ v = rgbComponentAlpha32with(p1, p2);
+ if (!(destDepth == 32)) {
+ /* begin rgbMap:from:to: */
+ if (((d = destDepth - 32)) > 0) {
+
+ /* Expand to more bits by zero-fill */
+ /* Transfer mask */
+
+ mask3 = (1 << 32) - 1;
+ srcPix = v << d;
+ mask3 = mask3 << d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << destDepth;
+ srcPix = srcPix << d;
+ v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << destDepth));
+ goto l1;
+ }
+ else {
+ if (d == 0) {
+ if (32 == 5) {
+ v = v & 32767;
+ goto l1;
+ }
+ if (32 == 8) {
+ v = v & 16777215;
+ goto l1;
+ }
+ v = v;
+ goto l1;
+ }
+ if (v == 0) {
+ v = v;
+ goto l1;
+ }
+ d = 32 - destDepth;
+
+ /* Transfer mask */
+
+ mask3 = (1 << destDepth) - 1;
+ srcPix = ((usqInt) v) >> d;
+ destPix = srcPix & mask3;
+ mask3 = mask3 << destDepth;
+ srcPix = ((usqInt) srcPix) >> d;
+ destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << destDepth));
+ if (destPix == 0) {
+ v = 1;
+ goto l1;
+ }
+ v = destPix;
+ goto l1;
+ }
+ l1: /* end rgbMap:from:to: */;
+ }
+ result = result | (v << ((i - 1) * destDepth));
+
+ /* slide left to next partition */
+
+ mask = mask << destDepth;
+ }
+ return result;
+}
+
+
/* Subract the pixels in the source and destination, color by color,
and return the sum of the absolute value of all the differences.
For non-rgb, return the number of differing pixels. */
@@ -5342,7 +6181,7 @@
sqInt bits;
sqInt targetBits;
- bits = targetBits = 0;
+ bits = (targetBits = 0);
if (sourceDepth <= 8) {
return null;
}
@@ -5682,7 +6521,8 @@
if (noSource) {
return 0;
}
- if (!(combinationRule == 34)) {
+ if (!((combinationRule == 34)
+ || (combinationRule == 41))) {
return 0;
}
if (!(sourceDepth == 32)) {
@@ -5691,6 +6531,33 @@
if (sourceForm == destForm) {
return 0;
}
+ if (combinationRule == 41) {
+ if (destDepth == 32) {
+ rgbComponentAlpha32();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ if (destDepth == 16) {
+ rgbComponentAlpha16();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ if (destDepth == 8) {
+ rgbComponentAlpha8();
+ affectedL = dx;
+ affectedR = dx + bbW;
+ affectedT = dy;
+ affectedB = dy + bbH;
+ return 1;
+ }
+ return 0;
+ }
if (destDepth < 8) {
return 0;
}
@@ -5745,10 +6612,10 @@
destHandle = (destHandle >> 1);
fn(destHandle, affectedL, affectedT, affectedR-affectedL, affectedB-affectedT);
- destBits = destPitch = 0;
+ destBits = (destPitch = 0);
destLocked = 1;
}
- if (!(noSource)) {
+ if (!noSource) {
sourceHandle = interpreterProxy->fetchPointerofObject(FormBitsIndex, sourceForm);
if ((sourceHandle & 1)) {
@@ -5759,7 +6626,7 @@
&& (sourceHandle == destHandle))) {
fn(sourceHandle, 0, 0, 0, 0);
}
- sourceBits = sourcePitch = 0;
+ sourceBits = (sourcePitch = 0);
}
}
hasSurfaceLock = 0;
@@ -5780,11 +6647,11 @@
noSource = ns;
if (noSource
|| ((bbW <= 0)
- || (bbH <= 0))) {
+ || (bbH <= 0))) {
/* zero width or height; noop */
- affectedL = affectedR = affectedT = affectedB = 0;
+ affectedL = (affectedR = (affectedT = (affectedB = 0)));
return null;
}
if (!(lockSurfaces())) {
@@ -5823,7 +6690,7 @@
/* calculate byte addr and delta, based on first word of data */
/* Note pitch is bytes and nWords is longs, not bytes */
- hDir = vDir = 1;
+ hDir = (vDir = 1);
destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
warpLoop();
@@ -6286,8 +7153,8 @@
/* begin pickWarpPixelAtX:y: */
if ((sx < 0)
|| ((sy < 0)
- || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+ || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
sourcePix = 0;
goto l15;
}
@@ -6312,8 +7179,8 @@
/* begin pickWarpPixelAtX:y: */
if ((sx < 0)
|| ((sy < 0)
- || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+ || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
sourcePix = 0;
goto l16;
}
@@ -6504,7 +7371,7 @@
/* Pick and average n*n subpixels */
- a = r = g = b = 0;
+ a = (r = (g = (b = 0)));
/* actual number of pixels (not clipped and not transparent) */
@@ -6518,8 +7385,8 @@
/* begin pickWarpPixelAtX:y: */
if ((xx < 0)
|| ((yy < 0)
- || ((((x1 = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x1 = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
+ || (((y1 = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
rgb = 0;
goto l1;
}
@@ -6565,7 +7432,7 @@
} while(!(((j -= 1)) == 0));
if ((nPix == 0)
|| ((combinationRule == 25)
- && (nPix < (((sqInt) (n * n) >> 1))))) {
+ && (nPix < (((sqInt) (n * n) >> 1))))) {
/* All pixels were 0, or most were transparent */
@@ -6665,8 +7532,8 @@
/* begin pickWarpPixelAtX:y: */
if ((sx < 0)
|| ((sy < 0)
- || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+ || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
sourcePix = 0;
goto l1;
}
@@ -6691,8 +7558,8 @@
/* begin pickWarpPixelAtX:y: */
if ((sx < 0)
|| ((sy < 0)
- || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+ || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+ || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
sourcePix = 0;
goto l2;
}
Modified: branches/Cog/unixbuild/mtbld/mvm
===================================================================
--- branches/Cog/unixbuild/mtbld/mvm 2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/unixbuild/mtbld/mvm 2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,5 +1,5 @@
#!/bin/sh
-test -f config.h || ../../platforms/unix/config/configure INTERP=cointerpmt --without-vm-display-fbdev --without-npsqueak CFLAGS="-g -O2 -msse2 -DNDEBUG -DCOGMTVM=1 -DDEBUGVM=0 -D_GNU_SOURCE -DITIMER_HEARTBEAT=1 -DNO_VM_PROFILE=1" LIBS=-lpthread
+test -f config.h || ../../platforms/unix/config/configure INTERP=cointerpmt --without-vm-display-fbdev --without-npsqueak CFLAGS="-g -O2 -msse2 -DNDEBUG -DCOGMTVM=1 -DDEBUGVM=0 -D_GNU_SOURCE -DITIMER_HEARTBEAT=1 -DNO_VM_PROFILE=1" LIBS=-lpthread
../../scripts/nukeversion
rm -rf ../../cogmtlinux
make install prefix=`readlink -f \`pwd\`/../../cogmtlinux`