[Vm-dev] VM Maker: VMMaker.oscog-nice.2909.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Dec 23 20:55:01 UTC 2020


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2909.mcz

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

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).

=============== Diff against VMMaker.oscog-eem.2908 ===============

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'
  	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 blendRB blendG |
+ 	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
+ 	<var: #blendRB type: 'unsigned int'>
+ 	<var: #blendG type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
+ 	<var: #alpha type: 'unsigned int'>
+ 	<var: #blendA 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)) + 16rFF. "blend alpha channels"
+ 	blendA := blendA + (blendA - 1 >> 8 bitAnd: 16rFF) >> 8 bitAnd: 16rFF. "divide by 255"
+ 
+ 	blendRB := ((sourceWord bitAnd: 16rFF00FF) * alpha) +
+ 				((destinationWord bitAnd: 16rFF00FF) * (blendA-alpha))
+ 				/ blendA.	"blend red and blue"
+ 
+ 	blendG := ((sourceWord bitAnd: 16r00FF00) * alpha) +
+ 				((destinationWord bitAnd: 16r00FF00) * (blendA-alpha))
+ 				/ blendA.	"blend green"
+ 	result := (blendRB 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 >> 8 bitAnd: 16rFF00FF). "scale red and blue components"
+ 	g := ((destinationWord bitAnd: 16r00FF00) * alpha >> 8 bitAnd: 16r00FF00). "scale green component"
+ 	^(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 rb 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: #rb type: 'unsigned int'>
+ 	<var: #g 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].
+ 	rb := (destinationWord bitAnd: 16rFF00FF) << 8 / alpha. "unscale red and blue components"
+ 	g := (destinationWord bitAnd: 16r00FF00) / alpha. "unscale green component"
+ 	carry := ((rb >> 8 bitAnd: 16rAA00AA) >> 1 bitOr: (rb >> 8 bitAnd: 16r550055) << 1)
+ 		bitOr: ((g bitAnd: 16r00AA00) >> 1 bitOr: (g bitAnd: 16r005500) << 1).
+ 	carry := (carry bitAnd: 16rCCCCCC) >> 2 bitOr: (carry bitAnd: 16r333333) << 2.
+ 	carry := (carry bitAnd: 16rF0F0F0) >> 4 bitOr: (carry bitAnd: 16r0F0F0F) << 4.
+ 	rgb := (rb bitAnd: 16rFF00FF) bitOr: (g << 8 bitAnd: 16r00FF00).
+ 	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'.!



More information about the Vm-dev mailing list