Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CopyBits and dual monitor configration



>> Locking the pixels in a pixmap is *always* mandatory before passing
>> that pixmap to CopyBits. The reason is that the call to CopyBits can
>> move memory - including the actual pixels in the pixmaps.
>>
>> See the sample listing at:
>>
>> http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw
>> -304.html#MARKER-9-27
>
> I'm sorry, but you are just not correct in this case. The CopyBits
> call will lock the pixels for you if you have not already done so.
>
> The reason that the code you are looking at on that page uses
> LockPixels is because it is drawing into an Offscreen GWorld. With an
> offscreen GWorld. The Offscreen GWorld may have been created such that
> it's pixels are purgeable. In the case of a purgeable Offscreen =
GWorld
> the LockPixels will insure that the pixel buffer is available for you
> to use by allocating them if they have been purged. That's why
> LockPixels returns a Boolean. If the pixels were purged and cannot be
> reallocated then LockPixels will return false.

Upon re-reading this post, I see that my language is entirely too=20
inaccurate and misleading and I failed to clarify an important point=20
that I meant to make. Unfortunately on my way out the door to have=20
dinner with my family, I screwed up and used the term "lock the pixels"=20=

when I meant locking the port bits. Please allow me to correct that=20
here.

The point I meant to make is that there are two different concepts=20
involved here and they have confusingly similar names. The first=20
concept is that of locking a PixMapHandle before using it. The second=20=

concept is that of preparing the backing store of a window for drawing=20=

by using the LockPortBits call. Because of the similarities between=20
the names of LockPixels/UnlockPixels and LockPortBits/UnlockPortBits it=20=

is easy to see where the two concepts can become confused.

Pay close attention to the routine names because there's going to be a=20=

lot of lock/unlock in this next bit.

A generalized statement about the difference between the two is that a=20=

QuickDraw programmer should use LockPixels/UnlockPixels when calling=20
CopyBits. A QuickDraw programmer without very special needs should=20
never have to call LockPortBits/UnlockPortBits.

In the case of calling CopyBits on GWorlds on Mac OS 9, it is very=20
important to make sure that the PixMapHandle is locked using LockPixels=20=

before making the call to CopyBits. The reason this is important is=20
because CopyBits only ever sees the dereferenced PixMapHandle and does=20=

not have the opportunity to make sure that handle will not move should=20=

it need to shuffle the heap. LockPixels can also be used to determine=20=

whether or not the pixels of an offscreen GWorld with a purgeable=20
PixMap have, in fact, been purged. (if they have been purged then the=20=

application should call UpdateGWorld to reallocate the pixels). On Mac=20=

OS X, in contrast, with the sparse virtual memory space there is very=20
little chance of the PixMapHandle moving or the pixels being purged. =20
In spite of that, Calling LockPixels/UnlockPixels is still a Good Idea=99=20=

on Mac OS X.

LockPortBits, in contrast, is used to ensure that the backing store of=20=

a window is available for drawing. In the normal course of an=20
application that uses QuickDraw or Core Graphics to draw into a window,=20=

the application should never have to call LockPortBits/UnlockPortBits=20
directly. The one case that this is important is if you want to=20
manipulate the backing store of your window by flipping bits at the=20
pixel level. In that case, you have to call=20
LockPortBits/UnlockPortBits to not only ensure that your window's base=20=

address is set up properly, but also to inform the operating system=20
when you are done with the backing store so it can flush your changes=20
forward (you might also have to call QDSetDirtyRegion).

If the original code is doing the Right Thing=99 and calling=20
LockPixels/UnlockPixels on the destination PixMapHandle then the=20
program should not have to call LockPortBits/UnlockPortBits on the=20
window's port. That should be handled by the LockPixels/UnlockPixels=20
pair. What I suspect is happening with the original code, however, is=20=

that neither LockPixels nor LockPortBits is being called. This leads=20
to the case where the PixMapHandle for the window was actually the=20
PixMapHandle for the screen, and not that of the back buffer of the=20
window as expected. Calling LockPortBits would actually fix the=20
problem, but it would be more correct to put in the call to LockPixels!

The code should look something like:

GWorldPtr myOffscreen =3D NewGWorld(...); /* plus additional setup */
CGrafPtr myWindowPort =3D GetWindowPort(myDestWindow);
GWorldPtr savedPort;

bool swapped =3D QDSwapPort(myWindowPort, &savedPort);
ForeColor(blackColor);
BackColor(whiteColor);

LockPixels(GetPortPixMap(myWindowPort));
CopyBits(
GetPortBitMapForCopyBits(myOffscreen),
GetPortBitMapForCopyBits(myWindowPort),
... other arguments here...);
UnlockPixels(GetPortPixMap(myWindowPort));
if(swapped)
QDSwapPort(savedPort, &savedPort);

The point that I originally objected to is that at no point in this=20
sequence should it be necessary to call LockPortBits. Where the post=20
above is confusing is that it seems to imply that LockPixels is not=20
necessary either. However that is not what I intended and is, in fact,=20=

wrong. in this case because it is probably what is going to call=20
LockPortBits for you.
--
Macintosh Software Engineering Consulting Services
Visit my resume at <http://homepage.mac.com/easco/RSTResume.html>

[demime 0.98b removed an attachment of type application/pkcs7-signature which had a name of smime.p7s]
_______________________________________________
carbon-development mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/carbon-development
Do not post admin requests to the list. They will be ignored.




Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.