Nicolas Cellier uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2717.mcz ==================== Summary ==================== Name: VMMaker.oscog-nice.2717 Author: nice Time: 22 February 2020, 9:27:55.723238 am UUID: 7e488f00-892c-4569-b600-422064393682 Ancestors: VMMaker.oscog-eem.2716 Fix the BitBlt bug for convex shape fill. The problem is that we are taking source one word too early (thus from previous row). This happens when taking hdir=-1 and it is related to preload (again!!). To guess if we must preload, we have to take the endBits when the direction is reversed due to overlap (hDir = -1) endBits := (sx + bbW - 1 bitAnd: pixPerM1) + 1 First error above: checkSourceOverlap has already done that: sx := sx + bbW - 1. So it must be: endBits := (sx bitAnd: pixPerM1) + 1 Then we build mask1: m1 := destMSB = (hDir > 0) ifTrue: [AllOnes >> (32 - (startBits * destDepth))] ifFalse: [AllOnes << (32 - (startBits * destDepth)) bitAnd: AllOnes]. Second error above: if we have reversed direction (hDir = -1), then we must build mask2: destMSB ifTrue: [mask2 := AllOnes << (32 - (endBits * destDepth)) bitAnd: AllOnes] ifFalse: [mask2 := AllOnes >> (32 - (endBits * destDepth))]. Replace mask2 by m1 and endBits by startBits (because startBits contains endBits if hDir=-1) And you see that the conditions destMSB is reversed... Last thing: on 64bits, mask1 and mask2 have been declared int64... But we only want 32 bits mask. That is why I have protected with the bitAnd: AllOnes (and thus removed the cCode:inSmalltalk: simulation guard) =============== Diff against VMMaker.oscog-eem.2716 =============== Item was changed: ----- Method: BitBltSimulation>>destMaskAndPointerInit (in category 'setup') ----- destMaskAndPointerInit "Compute masks for left and right destination words" | startBits pixPerM1 endBits | <inline: true> pixPerM1 := destPPW - 1. "A mask, assuming power of two" "how many pixels in first word" startBits := destPPW - (dx bitAnd: pixPerM1). "how many pixels in last word" endBits := (dx + bbW - 1 bitAnd: pixPerM1) + 1. destMSB ifTrue: [mask1 := AllOnes >> (32 - (startBits * destDepth)). + mask2 := AllOnes << (32 - (endBits * destDepth)) bitAnd: AllOnes] - mask2 := AllOnes << (32 - (endBits * destDepth))] ifFalse: + [mask1 := AllOnes << (32 - (startBits * destDepth)) bitAnd: AllOnes. - [mask1 := AllOnes << (32 - (startBits * destDepth)). mask2 := AllOnes >> (32 - (endBits * destDepth))]. - self cCode: [] inSmalltalk: - [mask1 := mask1 bitAnd: 16rFFFFFFFF. - mask2 := mask2 bitAnd: 16rFFFFFFFF]. "determine number of words stored per line; merge masks if only 1" bbW <= startBits ifTrue: [mask1 := mask1 bitAnd: mask2. mask2 := 0. nWords := 1] ifFalse: [nWords := bbW - startBits + pixPerM1 // destPPW + 1]. hDir := vDir := 1. "defaults for no overlap with source" "calculate byte addr and delta, based on first word of data" "Note pitch is bytes and nWords is longs, not bytes" destIndex := destBits + (dy * destPitch) + ((dx // destPPW) * 4). destDelta := destPitch * vDir - (4 * (nWords * hDir)) "byte addr delta"! Item was changed: ----- Method: BitBltSimulation>>sourceSkewAndPointerInit (in category 'setup') ----- sourceSkewAndPointerInit "This is only used when source and dest are same depth, ie, when the barrel-shift copy loop is used." | sxLowBits dxLowBits pixPerM1 startBits m1 | <inline: true> <var: 'm1' type: #'unsigned int'> self assert: (destPPW = sourcePPW and: [destMSB = sourceMSB and: [destDepth = sourceDepth]]). pixPerM1 := destPPW - 1. "A mask, assuming power of two" sxLowBits := sx bitAnd: pixPerM1. dxLowBits := dx bitAnd: pixPerM1. "how many pixels in first word" startBits := hDir > 0 ifTrue: [sourcePPW - (sx bitAnd: pixPerM1)] + ifFalse: [(sx bitAnd: pixPerM1) + 1]. + m1 := destMSB = (hDir > 0) - ifFalse: [(sx + bbW - 1 bitAnd: pixPerM1) + 1]. - m1 := destMSB ifTrue: [AllOnes >> (32 - (startBits * destDepth))] + ifFalse: [AllOnes << (32 - (startBits * destDepth)) bitAnd: AllOnes]. - ifFalse: [AllOnes << (32 - (startBits * destDepth))]. preload := bbW > startBits and: [(m1 bitAnd: mask1) ~= mask1]. "i.e. there are some missing bits" "calculate right-shift skew from source to dest" skew := destDepth * (sourceMSB ifTrue: [sxLowBits - dxLowBits] ifFalse: [dxLowBits - sxLowBits]). " -32..32 " preload ifTrue: [skew := skew < 0 ifTrue: [skew + 32] ifFalse: [skew - 32]]. "Calc byte addr and delta from longWord info" + sourceIndex := sourceBits + (sy * sourcePitch) + ((sx // sourcePPW) * 4). - sourceIndex := sourceBits + (sy * sourcePitch) + ((sx // (32 // sourceDepth)) * 4). "calculate increments from end of 1 line to start of next" sourceDelta := (sourcePitch * vDir) - (4 * (nWords * hDir)). preload ifTrue: "Compensate for extra source word fetched" [sourceDelta := sourceDelta - (4 * hDir)]. self deny: (preload and: [skew = 0]). self assert: (skew between: -31 and: 31)! |
Free forum by Nabble | Edit this page |