a question about sqInt displayObject(void)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

a question about sqInt displayObject(void)

johnmci

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.


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 <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: a question about sqInt displayObject(void)

Eliot Miranda-2
 
Hi John,

On Wed, Feb 10, 2010 at 11:28 AM, John M McIntosh <[hidden email]> 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 :)

HTH
Eliot



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 <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================





Reply | Threaded
Open this post in threaded view
|

Re: a question about sqInt displayObject(void)

Andreas.Raab
In reply to this post by johnmci
 
Hi John -

That's completely reasonable. If you check the Android VM, it basically
does the same thing when updating the bits inside Java:

http://code.google.com/p/squeak-android-vm/source/browse/trunk/project/jni/squeakvm.c

int
Java_org_squeak_android_SqueakVM_updateDisplay(JNIEnv *env, jobject self,
                                                jintArray bits, int w,
int h,
                                                int d, int left, int
top, int right, int bottom) {
   int row;
   sqInt formObj = interpreterProxy->displayObject();
   sqInt formBits = interpreterProxy->fetchPointerofObject(0, formObj);
   sqInt width = interpreterProxy->fetchIntegerofObject(1, formObj);
   sqInt height = interpreterProxy->fetchIntegerofObject(2, formObj);
   sqInt depth = interpreterProxy->fetchIntegerofObject(3, formObj);
   int *dispBits = interpreterProxy->firstIndexableField(formBits);

   if(depth != 32) {
     dprintf(4, "updateDisplay: Display depth %d\n", depth);
     return 0;
   }
   if(width != w) {
     dprintf(4, "updateDisplay: Display width is %d (expected %d)\n",
width, w);
   }
   if(height != h) {
     dprintf(4, "updateDisplay: Display width is %d (expected %d)\n",
height, h);
   }
   for(row = top; row < bottom; row++) {
         int ofs = width*row+left;
         (*env)->SetIntArrayRegion(env, bits, ofs, right-left,
dispBits+ofs);
   }
   return 1;
}


Cheers,
   - Andreas

John M McIntosh 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.
>
>
> 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 <[hidden email]>   Twitter:  squeaker68882
> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
> ===========================================================================
>
>
>
>