[Vm-dev] VM Maker: VMMaker-dtl.433.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Mar 6 23:28:35 UTC 2022


David T. Lewis uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-dtl.433.mcz

==================== Summary ====================

Name: VMMaker-dtl.433
Author: dtl
Time: 6 March 2022, 5:44:02.279 pm
UUID: 1a9d1fbe-9459-4275-84b8-b668eed57607
Ancestors: VMMaker-dtl.432

VMMaker 4.19.14
Add the new BitBlt rules from oscog (Nicolas Cellier)

Name: VMMaker.oscog-nice.2909
Author: nice
Time: 23 December 2020, 9:54:51.201058 pm
UUID: 6869c4f1-9d80-40c3-8409-7c05e087edf5
Ancestors: VMMaker.oscog-eem.2908

WIP: implement new BitBlt ops (rules) for alpha compositing

		"42" alphaScale:with:
		"43" alphaUnscale:with:
		"44" alphaBlendUnscaled:with:
		
This is a proposal implementation for https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/505

The generated C code compiles, but it's otherwise mostly yet unused and untested code. I commit it before I loose it.
There's probably more to do for letting accelerated code work (PI).

Name: VMMaker.oscog-nice.3169
Author: nice
Time: 24 February 2022, 1:53:42.760293 am
UUID: e2ca1296-dc0c-418e-b1ac-7def7ff9a33d
Ancestors: VMMaker.oscog-eem.3168

Fix alphaBlendUnscaled

some bits were leaking in the neighbour color.

Name: VMMaker.oscog-nice.3170
Author: nice
Time: 24 February 2022, 2:48:39.990237 pm
UUID: 6b851cd8-b485-1047-acfd-8adee37e3660
Ancestors: VMMaker.oscog-nice.3169

Revise the 3 new BitBlt rules again
(see https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/505)

- use a proper division by 255 (factor alpha/255) in alphaScale:with: instead of approximate factor alpha/256 previously
- use a proper rounding (by adding 16r80 before the division by 255) in alphaScale:with:
- split the unscale ops in 3 separate r/g/b channels, otherwise, when grouping rb, the division by alpha will leak red bits not only on green components but also on blue
- fixup the carry used for saturating the rbg components in case of 16rFF overflow in alphaUnscale:with:

Note: division by 255 can be checked thru this snippet (should answer 0):

	(0 to: 16rFF squared) inject: 0 into:
		[:max :num |
		| rat |
		rat := num + 16r80. "+ 16r80 for rounding"
		rat := rat + (rat - 1 >> 8 bitAnd: 16rFF) >> 8 bitAnd: 16rFF. "divide by 255"
		((num/255) rounded - rat) abs max: max].

=============== Diff against VMMaker-dtl.432 ===============

Item was changed:
  SmartSyntaxInterpreterPlugin subclass: #BitBltSimulation
+ 	instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight sourceWidth sourceHeight sourceDepth sourcePitch sourceBits sourcePPW sourceMSB destWidth destHeight destDepth destPitch destBits destPPW destMSB bitCount skew mask1 mask2 preload nWords destMask hDir vDir sourceIndex sourceDelta destIndex destDelta sx sy dx dy bbW bbH halftoneHeight noSource noHalftone halftoneBase sourceAlpha srcBitShift dstBitShift bitBltOop affectedL affectedR affectedT affectedB opTable maskTable ditherMatrix4x4 ditherThresholds16 ditherValues16 hasSurfaceLock warpSrcShift warpSrcMask warpAlignShift warpAlignMask warpBitShiftTable querySurfaceFn lockSurfaceFn unlockSurfaceFn isWarping cmFlags cmMask cmShiftTable cmMaskTable cmLookupTable cmBitsPerColor dither8Lookup componentAlphaModeColor componentAlphaModeAlpha ungammaLookupTable gammaLookupTable numGCsOnInvocation bitBltIsReceiver endOfDestination endOfSource'
+ 	classVariableNames: 'AllOnes AlphaIndex BBClipHeightIndex BBClipWidthIndex BBClipXIndex BBClipYIndex BBColorMapIndex BBDestFormIndex BBDestXIndex BBDestYIndex BBHalftoneFormIndex BBHeightIndex BBLastIndex BBRuleIndex BBSourceFormIndex BBSourceXIndex BBSourceYIndex BBWarpBase BBWidthIndex BBXTableIndex BEBitBltIndex BinaryPoint BlueIndex ColorMapFixedPart ColorMapIndexedPart ColorMapNewStyle ColorMapPresent CrossedX EndOfRun FixedPt1 FormBitsIndex FormDepthIndex FormHeightIndex FormWidthIndex GreenIndex OpTable OpTableSize RedIndex'
- 	instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight sourceWidth sourceHeight sourceDepth sourcePitch sourceBits sourcePPW sourceMSB destWidth destHeight destDepth destPitch destBits destPPW destMSB bitCount skew mask1 mask2 preload nWords destMask hDir vDir sourceIndex sourceDelta destIndex destDelta sx sy dx dy bbW bbH halftoneHeight noSource noHalftone halftoneBase sourceAlpha srcBitShift dstBitShift bitBltOop affectedL affectedR affectedT affectedB opTable maskTable ditherMatrix4x4 ditherThresholds16 ditherValues16 hasSurfaceLock warpSrcShift warpSrcMask warpAlignShift warpAlignMask warpBitShiftTable querySurfaceFn lockSurfaceFn unlockSurfaceFn isWarping cmFlags cmMask cmShiftTable cmMaskTable cmLookupTable cmBitsPerColor dither8Lookup componentAlphaModeColor componentAlphaModeAlpha ungammaLookupTable gammaLookupTable'
- 	classVariableNames: 'AllOnes AlphaIndex BBClipHeightIndex BBClipWidthIndex BBClipXIndex BBClipYIndex BBColorMapIndex BBDestFormIndex BBDestXIndex BBDestYIndex BBHalftoneFormIndex BBHeightIndex BBLastIndex BBRuleIndex BBSourceFormIndex BBSourceXIndex BBSourceYIndex BBWarpBase BBWidthIndex BBXTableIndex BinaryPoint BlueIndex ColorMapFixedPart ColorMapIndexedPart ColorMapNewStyle ColorMapPresent CrossedX EndOfRun FixedPt1 FormBitsIndex FormDepthIndex FormHeightIndex FormWidthIndex GreenIndex JitBltHookSize OpTable OpTableSize RedIndex'
  	poolDictionaries: ''
  	category: 'VMMaker-Interpreter'!
  
+ !BitBltSimulation commentStamp: 'nice 10/31/2020 23:39' prior: 0!
- !BitBltSimulation commentStamp: 'tpr 3/25/2013 16:50' prior: 0!
  This class implements BitBlt, much as specified in the Blue Book spec.
  
  Performance has been enhanced through the use of pointer variables such as sourceIndex and destIndex, and by separating several special cases of the inner loop.
  
  Operation has been extended to color, with support for 1, 2, 4, 8, 16, and 32-bit pixel sizes.  Conversion between different pixel sizes is facilitated by accepting an optional color map.
  
  In addition to the original 16 combination rules, this BitBlt supports
  	16	fail (for old paint mode)
  	17	fail (for old mask mode)
  	18	sourceWord + destinationWord
  	19	sourceWord - destinationWord
  	20	rgbAdd: sourceWord with: destinationWord
  	21	rgbSub: sourceWord with: destinationWord
  	22	OLDrgbDiff: sourceWord with: destinationWord
  	23	OLDtallyIntoMap: destinationWord -- old vers doesn't clip to bit boundary
  	24	alphaBlend: sourceWord with: destinationWord
  	25	pixPaint: sourceWord with: destinationWord
  	26	pixMask: sourceWord with: destinationWord
  	27	rgbMax: sourceWord with: destinationWord
  	28	rgbMin: sourceWord with: destinationWord
  	29	rgbMin: sourceWord bitInvert32 with: destinationWord
  	30	alphaBlendConst: sourceWord with: destinationWord -- alpha passed as an arg
  	31	alphaPaintConst: sourceWord with: destinationWord -- alpha passed as an arg
  	32	rgbDiff: sourceWord with: destinationWord
  	33	tallyIntoMap: destinationWord
  	34	alphaBlendScaled: sourceWord with: destinationWord
  	35 alphaBlendScaled: sourceWord with:	"unused here - only used by FXBlt"
  	36 alphaBlendScaled: sourceWord with:	"unused here - only used by FXBlt"
  	37 rgbMul: sourceWord with: destinationWord
  	38 pixSwap: sourceWord with: destinationWord
  	39 pixClear: sourceWord with: destinationWord
  	40 fixAlpha: sourceWord with: destinationWord
  	41 rgbComponentAlpha: sourceWord with: destinationWord
+ 	42 alphaScale: ignoredSourceWord with: destinationWord
+ 	43 alphaUnscale: ignoredSourceWord with: destinationWord
+ 	44	alphaBlendUnscaled: sourceWord with: destinationWord
  
  This implementation has also been fitted with an experimental "warp drive" that allows abritrary scaling and rotation (and even limited affine deformations) with all BitBlt storage modes supported.
  
  To add a new rule to BitBlt...
  	1.  add the new rule method or methods in the category 'combination rules' of BBSim
  	2.  describe it in the class comment  of BBSim and in the class comment for BitBlt
  	3.  add refs to initializeRuleTable in proper positions
  	4.  add refs to initBBOpTable, following the pattern
  !

Item was changed:
  ----- Method: BitBltSimulation class>>initializeRuleTable (in category 'initialization') -----
  initializeRuleTable
  	"BitBltSimulation initializeRuleTable"
  	"**WARNING** You MUST change initBBOpTable if you change this"
  	OpTable := #(
  		"0" clearWord:with:
  		"1" bitAnd:with:
  		"2" bitAndInvert:with:
  		"3" sourceWord:with:
  		"4" bitInvertAnd:with:
  		"5" destinationWord:with:
  		"6" bitXor:with:
  		"7" bitOr:with:
  		"8" bitInvertAndInvert:with:
  		"9" bitInvertXor:with:
  		"10" bitInvertDestination:with:
  		"11" bitOrInvert:with:
  		"12" bitInvertSource:with:
  		"13" bitInvertOr:with:
  		"14" bitInvertOrInvert:with:
  		"15" destinationWord:with:
  		"16" destinationWord:with: "unused - was old paint"
  		"17" destinationWord:with: "unused - was old mask"
  		"18" addWord:with:
  		"19" subWord:with:
  		"20" rgbAdd:with:
  		"21" rgbSub:with:
  		"22" OLDrgbDiff:with:
  		"23" OLDtallyIntoMap:with:
  		"24" alphaBlend:with:
  		"25" pixPaint:with:
  		"26" pixMask:with:
  		"27" rgbMax:with:
  		"28" rgbMin:with:
  		"29" rgbMinInvert:with:
  		"30" alphaBlendConst:with:
  		"31" alphaPaintConst:with:
  		"32" rgbDiff:with:
  		"33" tallyIntoMap:with:
  		"34" alphaBlendScaled:with:
  
  		"35" alphaBlendScaled:with:	"unused here - only used by FXBlt"
  		"36" alphaBlendScaled:with:	"unused here - only used by FXBlt"
  		"37" rgbMul:with:
  		"38" pixSwap:with:
  		"39" pixClear:with:
  		"40" fixAlpha:with:
  		"41" rgbComponentAlpha:with:
+ 		"42" alphaScale:with:
+ 		"43" alphaUnscale:with:
+ 		"44" alphaBlendUnscaled:with:
  	).
  	OpTableSize := OpTable size + 1.  "0-origin indexing"
  !

Item was added:
+ ----- Method: BitBltSimulation>>alphaBlendUnscaled:with: (in category 'combination rules') -----
+ alphaBlendUnscaled: sourceWord with: destinationWord
+ 	"Blend sourceWord with destinationWord using the alpha value from both sourceWord and destinationWord.
+ 	Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.
+ 	The alpha channel and color produced are
+ 
+ 		srcAlpha + (destAlpha*(1-srcAlpha))
+ 		(srcAlpha*srcColor + (destAlpha*(1-srcAlpha)*dstColor)) / (srcAlpha + (destAlpha*(1-srcAlpha)))
+ 
+ 	In contrast to alphaBlend:with: the method does not assume that destination form is opaque.
+ 	In contrast to alphaBlendScaled:with: the method does not assume that colors have been pre-scaled (muliplied) by alpha channel."
+ 	| alpha blendA result blendR blendB blendG |
+ 	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: 'sourceWord' type: #'unsigned int'>
+ 	<var: 'destinationWord' type: #'unsigned int'>
+ 	<var: 'blendA' type: #'unsigned int'>
+ 	<var: 'blendR' type: #'unsigned int'>
+ 	<var: 'blendG' type: #'unsigned int'>
+ 	<var: 'blendB' type: #'unsigned int'>
+ 	<var: 'result' type: #'unsigned int'>
+ 	<var: 'alpha' type: #'unsigned int'>
+ 	alpha := sourceWord >> 24.  "High 8 bits of source pixel, assuming ARGB encoding"
+ 	alpha = 0 ifTrue: [ ^ destinationWord ].
+ 	alpha = 255 ifTrue: [ ^ sourceWord ].
+ 	
+ 	blendA := 16rFF * alpha + (16rFF - alpha * (destinationWord >> 24)) + 16r80. "blend alpha channels"
+ 	blendA := blendA + (blendA - 1 >> 8 bitAnd: 16rFF) >> 8 bitAnd: 16rFF. "divide by 255"
+ 
+ 	blendR := ((sourceWord bitAnd: 16rFF0000) * alpha) +
+ 				((destinationWord bitAnd: 16rFF0000) * (blendA-alpha))
+ 				+(blendA<<15)
+ 				// blendA bitAnd: 16rFF0000.	"blend red"
+ 					
+ 	blendG := ((sourceWord bitAnd: 16r00FF00) * alpha) +
+ 				((destinationWord bitAnd: 16r00FF00) * (blendA-alpha))
+ 				+(blendA<<7)
+ 				// blendA bitAnd: 16r00FF00.	"blend green"
+ 
+ 	blendB := ((sourceWord bitAnd: 16r0000FF) * alpha) +
+ 				((destinationWord bitAnd: 16r0000FF) * (blendA-alpha))
+ 				+(blendA>>1)
+ 				// blendA bitAnd: 16r0000FF.	"blend blue"
+ 					
+ 	result := ((blendR bitOr: blendB) bitOr: blendG) bitOr: blendA << 24.
+ 	^ result
+ !

Item was added:
+ ----- Method: BitBltSimulation>>alphaScale:with: (in category 'combination rules') -----
+ alphaScale: sourceWord with: destinationWord
+ 	"Scale (premultiply) the destination with its alpha channel.
+ 	Note that sourceWord is ignored."
+ 	| alpha rb g |
+ 	<inline: false>	"Do NOT inline this into optimized loops"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: 'sourceWord' type: #'unsigned int'>
+ 	<var: 'destinationWord' type: #'unsigned int'>
+ 	<var: 'rb' type: #'unsigned int'>
+ 	<var: 'g' type: #'unsigned int'>
+ 	<var: 'alpha' type: #'unsigned int'>
+ 	alpha := destinationWord >> 24.  "High 8 bits is opacity (ARGB format)"
+ 	rb := (destinationWord bitAnd: 16rFF00FF) * alpha  + 16r800080. "scale red and blue components"
+ 	rb := rb + (rb - 16r010001 >> 8 bitAnd: 16rFF00FF) >> 8 bitAnd: 16rFF00FF. "divide by 255"
+ 	g := (destinationWord bitAnd: 16r00FF00) * alpha  + 16r008000. "scale green component"
+ 	g := g + (g - 16r000100 >> 8 bitAnd: 16r00FF00) >> 8 bitAnd: 16r00FF00. "divide by 255"
+ 	^(g bitOr: rb) bitOr: (destinationWord bitAnd: 16rFF000000) "recompose"!

Item was added:
+ ----- Method: BitBltSimulation>>alphaUnscale:with: (in category 'combination rules') -----
+ alphaUnscale: sourceWord with: destinationWord
+ 	"Unscale (divide) the destination with its alpha channel.
+ 	Note that sourceWord is ignored."
+ 	| alpha r b g rgb carry |
+ 	<inline: false>	"Do NOT inline this into optimized loops"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: 'sourceWord' type: #'unsigned int'>
+ 	<var: 'destinationWord' type: #'unsigned int'>
+ 	<var: 'r' type: #'unsigned int'>
+ 	<var: 'g' type: #'unsigned int'>
+ 	<var: 'b' type: #'unsigned int'>
+ 	<var: 'rgb' type: #'unsigned int'>
+ 	<var: 'alpha' type: #'unsigned int'>
+ 	<var: 'carry' type: #'unsigned int'>
+ 	alpha := destinationWord >> 24.  "High 8 bits is opacity (ARGB format)"
+ 	alpha = 0 ifTrue: [^0].
+ 	r := (destinationWord bitAnd: 16rFF0000) * 255 + (alpha+1<<15) // alpha. "unscale red components"
+ 	g := (destinationWord bitAnd: 16r00FF00) * 255 + (alpha+1<<7)  // alpha. "unscale green component"
+ 	b := (destinationWord bitAnd: 16r0000FF) * 255 + (alpha+1>>1)  // alpha. "unscale blue components"
+ 	carry := (((r bitAnd: 16rFF000000) bitOr: (g bitAnd: 16rFF0000)) bitOr: (b bitAnd: 16rFF00)) >> 8.
+ 	carry := carry bitOr: ((carry bitAnd: 16rAAAAAA) >> 1 bitOr: (carry bitAnd: 16r555555) << 1).
+ 	carry := carry bitOr: ((carry bitAnd: 16rCCCCCC) >> 2 bitOr: (carry bitAnd: 16r333333) << 2).
+ 	carry := carry bitOr: ((carry bitAnd: 16rF0F0F0) >> 4 bitOr: (carry bitAnd: 16r0F0F0F) << 4).
+ 	rgb := ((r bitAnd: 16rFF0000) bitOr: (g bitAnd: 16r00FF00)) bitOr: (b bitAnd: 16r0000FF).
+ 	rgb := rgb bitOr: carry.  "saturate RGB components if division overflows"
+ 	^rgb bitOr: (destinationWord bitAnd: 16rFF000000) "restore alpha"!

Item was changed:
  ----- Method: BitBltSimulation>>initBBOpTable (in category 'initialize-release') -----
  initBBOpTable
  	self cCode: 'opTable[0+1] = (void *)clearWordwith'.
  	self cCode: 'opTable[1+1] = (void *)bitAndwith'.
  	self cCode: 'opTable[2+1] = (void *)bitAndInvertwith'.
  	self cCode: 'opTable[3+1] = (void *)sourceWordwith'.
  	self cCode: 'opTable[4+1] = (void *)bitInvertAndwith'.
  	self cCode: 'opTable[5+1] = (void *)destinationWordwith'.
  	self cCode: 'opTable[6+1] = (void *)bitXorwith'.
  	self cCode: 'opTable[7+1] = (void *)bitOrwith'.
  	self cCode: 'opTable[8+1] = (void *)bitInvertAndInvertwith'.
  	self cCode: 'opTable[9+1] = (void *)bitInvertXorwith'.
  	self cCode: 'opTable[10+1] = (void *)bitInvertDestinationwith'.
  	self cCode: 'opTable[11+1] = (void *)bitOrInvertwith'.
  	self cCode: 'opTable[12+1] = (void *)bitInvertSourcewith'.
  	self cCode: 'opTable[13+1] = (void *)bitInvertOrwith'.
  	self cCode: 'opTable[14+1] = (void *)bitInvertOrInvertwith'.
  	self cCode: 'opTable[15+1] = (void *)destinationWordwith'.
  	self cCode: 'opTable[16+1] = (void *)destinationWordwith'.
  	self cCode: 'opTable[17+1] = (void *)destinationWordwith'.
  	self cCode: 'opTable[18+1] = (void *)addWordwith'.
  	self cCode: 'opTable[19+1] = (void *)subWordwith'.
  	self cCode: 'opTable[20+1] = (void *)rgbAddwith'.
  	self cCode: 'opTable[21+1] = (void *)rgbSubwith'.
  	self cCode: 'opTable[22+1] = (void *)OLDrgbDiffwith'.
  	self cCode: 'opTable[23+1] = (void *)OLDtallyIntoMapwith'.
  	self cCode: 'opTable[24+1] = (void *)alphaBlendwith'.
  	self cCode: 'opTable[25+1] = (void *)pixPaintwith'.
  	self cCode: 'opTable[26+1] = (void *)pixMaskwith'.
  	self cCode: 'opTable[27+1] = (void *)rgbMaxwith'.
  	self cCode: 'opTable[28+1] = (void *)rgbMinwith'.
  	self cCode: 'opTable[29+1] = (void *)rgbMinInvertwith'.
  	self cCode: 'opTable[30+1] = (void *)alphaBlendConstwith'.
  	self cCode: 'opTable[31+1] = (void *)alphaPaintConstwith'.
  	self cCode: 'opTable[32+1] = (void *)rgbDiffwith'.
  	self cCode: 'opTable[33+1] = (void *)tallyIntoMapwith'.
  	self cCode: 'opTable[34+1] = (void *)alphaBlendScaledwith'.
  	self cCode: 'opTable[35+1] = (void *)alphaBlendScaledwith'.
  	self cCode: 'opTable[36+1] = (void *)alphaBlendScaledwith'.	
  	self cCode: 'opTable[37+1] = (void *)rgbMulwith'.
  	self cCode: 'opTable[38+1] = (void *)pixSwapwith'.
  	self cCode: 'opTable[39+1] = (void *)pixClearwith'.
  	self cCode: 'opTable[40+1] = (void *)fixAlphawith'.
+ 	self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'.
+ 	self cCode: 'opTable[42+1] = (void *)alphaScalewith'.
+ 	self cCode: 'opTable[43+1] = (void *)alphaUnscalewith'.
+ 	self cCode: 'opTable[44+1] = (void *)alphaBlendUnscaledwith'.!
- 	self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'.!

Item was changed:
  ----- Method: VMMaker class>>versionString (in category 'version testing') -----
  versionString
  
  	"VMMaker versionString"
  
+ 	^'4.19.14'!
- 	^'4.19.13'!



More information about the Vm-dev mailing list