[Vm-dev] a question about sqInt displayObject(void)

Eliot Miranda eliot.miranda at gmail.com
Wed Feb 10 20:01:47 UTC 2010

Hi John,

On Wed, Feb 10, 2010 at 11:28 AM, John M McIntosh <
johnmci at smalltalkconsulting.com> wrote:

> Ok, I'm working on an iPhone project where I have to consider what is going
> on with the Squeak Drawing cycle.
> The original logic takes the
>                ioShowDisplay(dispBitsIndex, w, h, d, left, right, top,
> bottom);
> and builds CGImageRefs from the dispBitsIndex data. This is an immutable
> object and actually uses Copy On Write Virtual Paging logic
> to ensure what the bits were when ioShowDisplay was called are what they
> will be when it's drawn.
> Usually ioShowDisplay is followed by a ForceDisplayUpdate which would then
> trigger the VM to take the queue of CGImageRefs (zero or more)  and draw
> them to the screen. This entails invalidating the combined rectangle(s), and
> waiting for the video sync logic to catch up and render the CGImageRef(s) to
> the drawing surface.
> There is a case where if you use warpblt then
> showDisplayBitsLeftTopRightBottom is uses and doesn't do the
>  ioForceDisplayUpdate. This is triggered by
> the primitive 231 code.  However on both the Macintosh and iPhone I have a
> dead man's timer and fire the primitiveForceDisplayUpdate if a draw is
> pending and
> oh say about 20 millisecond passes. This ensure the queue doesn't go to
> infinity (I've a production example of that...)
> This works fine on os-x because we write to  a window backing store but
> only flush the data to the window server for drawing based on the
> forceupdate.
> But on the iPhone it's different.
> We draw the CGImageRefs, BUT at some point the graphic layer can flush the
> content or part of the content and expect you to redraw eveything. However I
> don't have any of that information, or I didn't think I did, so I get black
> chunks of nothingness....
> I've moved from something rather complex, tricky and broken on the iPhone
> to something more simple which makes a copy of all the drawing. But it's
> painfully slow.
> Last night I got to thinking, where *does* the data come from.   So it
> appears and people can help confirm this, that Squeak *always* draws the
> data to the pointer in specialObjectsOops ->TheDisplay, found via sqInt
> displayObject(void).
> I recall that Tim had a hook for the ARM code to make the memory pointer
> not point to an area in Squeak OOps space, but to point it to video memory?
> Anyway I'm thinking here I should be able to at ForceDisplayUpdate time
> take the recorded rectangle data from ioShowDisplay and pull the bits
> directly from
> specialObjectsOops ->TheDisplay
> So anyone think this is not feasible?   I'd also look at doing this on OS-X
> since it avoids building the intern  CGImageRefs.

 Cog does something similar to reference the native method associated with a
bytecoded method.  If a bytecoded method has been compiled to machine code
by the JIT the its methodHeader word, which is usually a SmallInteger, gets
replaced by the address of its machine code method's header.  Each native
method starts with a structure holding things like the saved methodHeader,
the selector, how big it is, etc.  To fool the garbage collector into
thinking that the native method is an object that it doesn't need to worry
about the first word of the header is the object header for a byte object
with a compact class.  Nothing more is needed because the native method zone
is below the heap and so all references from bytecode method methodHeaders
that refer to native methods look like objects below youngStart, and if you
look at ObjectMemory>>markAndTrace: you'll see it doesn't mark old objects.

So if you want to create a remote frame buffer that looks like an object,
the easy way, if possible, is to place the frame buffer below the heap, and
put a word in front of it that contains the following value:

    (16 << 12 "CompactClassIndex 16, or Bitmap") + HeaderTypeShort

Then it'll look to the GC like a Bitmap object tat is always in oldSpace and
so never to be mucked with.

Oh, but this will cause at: and at:put: to fail because it looks like a
zero-length object.  So instead you should use a three word header with the
same compact class index and the right size value in the size field.  Can't
synthesize that off the top of my head, but you probably can.  Please let me
know what it is :)


> ioShowDisplay
>        displayBitsOfLeftTopRightBottom
>                fullDisplayUpdate
>                        Platform usage, not used on mac.
>                        !ioForceDisplayUpdate!
>                primitiveShowDisplayRect
>                        !ioForceDisplayUpdate!
>                        Primitive 127
>                                Via
> DisplayScreen>>primShowRectLeft:right:top:bottom:
>                                Via
> DisplayScreen>>primRetryShowRectLeft:right:top:bottom:
>                reverseDisplayFromto
>                        debugging code used by DoAssertionChecks
>                        !ioForceDisplayUpdate!
>                showDisplayBitsLeftTopRightBottom
>                        **** only user of deferDisplayUpdates
>                        various places from BitBlt Plugin
>        primitiveForceDisplayUpdate
>                        Primitive 231
> sqInt displayObject(void) {
>        return longAt((foo->specialObjectsOop + BaseHeaderSize) +
> (TheDisplay << ShiftForWord));
> }
> --
> ===========================================================================
> John M. McIntosh <johnmci at smalltalkconsulting.com>   Twitter:
>  squeaker68882
> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
> ===========================================================================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100210/06662826/attachment.htm

More information about the Vm-dev mailing list