[Vm-dev] VM Maker: VMMaker-tpr.309.mcz

Henrik Johansen henrik.s.johansen at veloxit.no
Fri Mar 22 08:59:41 UTC 2013


I feel your pain!
I vaguely remember speeding up that particular method some years ago by simply reimplementing it in the image … then failing to publish the results as I started refactoring Form in the process (think; anonymous subclasses specialized for each bit-depth, rather than the currently massive amounts of in-method case statements), which I never got around to finishing :(

Cheers,
Henry

On Mar 22, 2013, at 12:01 AM, commits at source.squeak.org wrote:

> 
> tim Rowledge uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker-tpr.309.mcz
> 
> ==================== Summary ====================
> 
> Name: VMMaker-tpr.309
> Author: tpr
> Time: 21 March 2013, 11:58:18.556 pm
> UUID: 0469a647-ba94-4bcf-91b0-99e81776473c
> Ancestors: VMMaker-dtl.308
> 
> Oh, hooray; is thing woring now? Can we finally save this damned tiny  change?It's only taken *all day*.
> Try again; add a tiny plugin to make the surprisingly frequent Form>pixelValueAt: faster - ie don't do an entire bitblt for it.
> This first version handles 1/2/4/8/16 & 32 bpp but not LSB bitmaps.
> 
> =============== Diff against VMMaker-dtl.308 ===============
> 
> Item was changed:
>  ----- Method: BitBltSimulation>>rgbMul:with: (in category 'combination rules') -----
>  rgbMul: sourceWord with: destinationWord
>  	<inline: false>
>  	destDepth < 16 ifTrue:
>  		["Mul each pixel separately"
>  		^ self partitionedMul: sourceWord with: destinationWord
>  						nBits: destDepth nPartitions: destPPW].
>  	destDepth = 16 ifTrue:
>  		["Mul RGB components of each pixel separately"
>  		^ (self partitionedMul: sourceWord with: destinationWord
>  						nBits: 5 nPartitions: 3)
>  		+ ((self partitionedMul: sourceWord>>16 with: destinationWord>>16
>  						nBits: 5 nPartitions: 3) << 16)]
>  	ifFalse:
>  		["Mul RGBA components of the pixel separately"
>  		^ self partitionedMul: sourceWord with: destinationWord
>  						nBits: 8 nPartitions: 4]
> 
>  "	| scanner |
>  	Display repaintMorphicDisplay.
>  	scanner := DisplayScanner quickPrintOn: Display.
> + 	MessageTally time: [0 to: 760 by: 4 do:  [:y |scanner drawString: 'qwrepoiuasfd=)(/&()=#!!ªlkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,Mqwrepoiuasfd=)(/&()=#!!ªlkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,M1234124356785678' at: 0 at y]]. "!
> - 	MessageTally time: [0 to: 760 by: 4 do:  [:y |scanner drawString: 'qwrepoiuasfd=)(/&()=#!!°lkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,Mqwrepoiuasfd=)(/&()=#!!°lkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,M1234124356785678' at: 0 at y]]. "!
> 
> Item was added:
> + SmartSyntaxInterpreterPlugin subclass: #PixelValuePeekPlugin
> + 	instanceVariableNames: ''
> + 	classVariableNames: 'AllOnes FormBitsIndex FormDepthIndex FormHeightIndex FormWidthIndex'
> + 	poolDictionaries: ''
> + 	category: 'VMMaker-Plugins'!
> + 
> + !PixelValuePeekPlugin commentStamp: 'tpr 3/14/2013 15:40' prior: 0!
> + I provide a primitive to quickly peek at the pixel value of a Form at a point; thus removing the need for a full-blown BitBlt>bitPeekerFromForm:!
> 
> Item was added:
> + ----- Method: PixelValuePeekPlugin class>>initialize (in category 'initialization') -----
> + initialize
> + "PixelValuePeekPlugin initialize"
> + 	"Mask constants"
> + 	AllOnes := 16rFFFFFFFF.
> + 
> + 
> + 	"Form fields"
> + 	FormBitsIndex := 0.
> + 	FormWidthIndex := 1.
> + 	FormHeightIndex := 2.
> + 	FormDepthIndex := 3!
> 
> Item was added:
> + ----- Method: PixelValuePeekPlugin>>primitivePixelValueAtX:y: (in category 'system primitives') -----
> + primitivePixelValueAtX: xVal y: yVal
> + 	"returns the single pixel at x at y.
> + 	It does not handle LSB bitmaps right now.
> + 	If x or y are < 0, return 0 to indicate transparent (cf BitBlt>bitPeekerFromForm: usage).
> + 	Likewise if x>width or y>depth.
> + 	Fail if the rcvr doesn't seem to be a Form, or x|y seem wrong"
> + 	| rcvr bitmap width height depth ppW stride word mask shift pixel |
> + 	rcvr := self primitive: 'primitivePixelValueAt' parameters: #(SmallInteger SmallInteger) receiver: #Oop.
> + 	
> + 	"possible quick exit if x or y is -ve"
> + 	(xVal < 0 or: [ yVal < 0 ] ) ifTrue:[^interpreterProxy integerObjectOf: 0].
> + 	"check that rcvr is plausibly a Form or subclass"	
> + 	rcvr := interpreterProxy stackValue: interpreterProxy methodArgumentCount.
> + 	((interpreterProxy isPointers: rcvr) and: [(interpreterProxy slotSizeOf: rcvr) >= 4])
> + 		ifFalse: [^interpreterProxy primitiveFail].
> + 
> + 	"get the bits oop and width/height/depth"
> + 	bitmap := interpreterProxy fetchPointer: FormBitsIndex ofObject: rcvr.
> + 	width := interpreterProxy fetchInteger: FormWidthIndex ofObject: rcvr.
> + 	height := interpreterProxy fetchInteger: FormHeightIndex ofObject: rcvr.
> + 	depth := interpreterProxy fetchInteger: FormDepthIndex ofObject: rcvr.
> + 	"if width/height/depth are not integer, fail"
> + 	interpreterProxy failed ifTrue:[^nil].
> + 
> + 	"possible quick exit if x or y is >= extent of form. This also catches cases where the width/height are < 0"
> + 	(xVal >= width or: [ yVal >= height ] ) ifTrue:[^interpreterProxy integerObjectOf: 0].
> + 
> + 	"we don't handle LSB Forms yet"
> + 	depth < 0 ifTrue:[^interpreterProxy primitiveFail].
> + 	
> + 	"OK so now we know we have a plausible Form, the width/height/depth/x/y are all reasonable and it's time to plunder the bitmap"
> + 	ppW := 32//depth. "pixels in each word"
> + 	stride := (width + (ppW  -1)) // ppW. "how many words per rox of pixels"
> + 	word := interpreterProxy fetchLong32:(yVal * stride) + (xVal//ppW) + 1 ofObject: bitmap. "load the word that contains our target"
> + 	mask := 16rFFFFFFFF >> (32 - depth). "make a mask to isolate the pixel within that word"
> + 	shift := 32 - (((xVal bitAnd: ppW-1) + 1) * depth). "this is the tricky MSB part - we mask the xVal to find how far into the word we need, then add 1 for the pixel we're looking for, then * depth to get the bit shift"
> + 	pixel := (word >> shift) bitAnd: mask. "shift, mask and dim the lights"
> + 	^interpreterProxy integerObjectOf: pixel "pop the incoming and push our answer"
> + !
> 



More information about the Vm-dev mailing list