[OpenJDK 2D-Dev] <AWT Dev> [8] Review request for 8011059 [macosx] Make JDK demos look perfect on retina displays

Alexander Scherbatiy alexandr.scherbatiy at oracle.com
Thu Nov 21 05:41:59 PST 2013


On 11/20/2013 3:17 PM, Jim Graham wrote:
> In looking through the ToolkitImage code some more it occurs to me 
> that it was already designed (moreso in a previous life) to hold onto 
> multiple representations of the image anyway.  In a prior life in 1.0 
> and 1.1 it held separate ImageRepresentation objects for each size it 
> was scaled to (via drawImage(w,h)), but that was simplified to a 
> single ImageRep when we converted to Java2D and started doing scaling 
> on the fly for all drawImage() operations. Still, the concept of an 
> alternate resolution version of the image is probably more in line 
> with the ImageRepresentation object within the ToolkitImage than in 
> having multiple ToolkitImage objects and a wrapper for them.
>
> This would also deal more naturally with the ImageObserver issue since 
> there really would be only one Image and SG2D would not deal with the 
> sub-representations, it would be dealt with in the DrawImage pipeline 
> code when it queries the ToolkitImage for the ImageRepresentation object.
>
> In the end, I think that design would be simpler overall, would it be 
> possible to shift those gears for this fix?  If not, we should 
> consider it for a near-term future cleanup task perhaps...

     I think that it would be better to postpone this cleanup to a 
near-term future task.

    Thanks,
    Alexandr.


>
>             ...jim
>
> On 11/19/2013 7:58 PM, Jim Graham wrote:
>> Based on the information below, I have the following suggestions...
>>
>> We should probably allow asynchronous loading of the scaled 
>> resolution variants.  This is a minor variation of what the 
>> ImageObserver was originally designed for, but technically might 
>> violate some developer's expectations if they have only dealt with a 
>> post-Java2D version of Java.  Some education might be helpful here.
>>
>> The wording on drawImage(dxy12, sxy12) should probably be reworded to 
>> indicate that asynchronous scaling would not happen, but alternate 
>> versions of the image may be accessed.
>>
>> In all cases, if the version of the image that we would ideally want 
>> to show hasn't been loaded, but the standard version has (or if @2x 
>> was loaded, but we want the regular version too?) then we should 
>> probably go with the version that was loaded, but still trigger the 
>> loading of the alternate version and notify their Observer as it is 
>> loaded.
>>
>> I also examined the places in the code where we notify the 
>> ImageObserver.  A search for the observer method should show all 
>> places we call it, but the primary ones look like they are fairly few 
>> places.  If we tag the resolution variant images with the composite 
>> image from which they came, then we can have those few places do 
>> something like:
>>
>> Image obsimg = (img instanceof SunToolkitImage) ? (() 
>> img).getObservedImage() : img;
>>
>> I think in most cases the img is already known to be our internal 
>> SunToolkit image and so we don't even need to check instanceof...
>>
>>              ...jim
>>
>> On 11/19/2013 7:01 PM, Jim Graham wrote:
>>> I did some more reading about the various ways in which the 
>>> ImageObserver is used and noticed the following points, some of 
>>> which may be to our advantage.
>>>
>>> Many of the drawImage() calls mention that they will notify the 
>>> observer as the image is "scaled or converted for the output 
>>> device".  I believe in the world before 2D, we would often have to 
>>> load or convert the image asynchronously for various changes in the 
>>> output.  When we created the 2D interface and added some on-the-fly 
>>> image scaling code, we mentioned that scaling was no longer 
>>> asynchronous, but technically the API is still designed for 
>>> asynchronous operations when the rendering parameters change.
>>>
>>> However, the drawImage() call that takes 8 parameters dxy12, sxy12 - 
>>> specifically includes the words:
>>>
>>>       * This method always uses the unscaled version of the image
>>>       * to render the scaled rectangle and performs the required
>>>       * scaling on the fly. It does not use a cached, scaled version
>>>       * of the image for this operation. Scaling of the image from 
>>> source
>>>       * to destination is performed such that the first coordinate
>>>       * of the source rectangle is mapped to the first coordinate of
>>>       * the destination rectangle, and the second source coordinate is
>>>       * mapped to the second destination coordinate. The subimage is
>>>       * scaled and flipped as needed to preserve those mappings.
>>>      public abstract boolean drawImage(Image img,
>>>                                        int dx1, int dy1, int dx2, 
>>> int dy2,
>>>                                        int sx1, int sy1, int sx2, 
>>> int sy2,
>>>                                        ImageObserver observer);
>>>
>>> which basically, at the time it was created in 1.1, was an opt "out" 
>>> of the asynchronous operations that might happen when you scaled an 
>>> image with drawImage(xywh).  As worded, this would suggest that this 
>>> method does not use the @2x version and always uses the default 
>>> resolution version, but those words were not put there for this 
>>> particular intent, they were put there to indicate that we weren't 
>>> going to do an off-line scaling of the pixels which sometimes 
>>> happened in 1.0.x and possibly 1.1 (for the other calls that 
>>> predated 1.1 until Java2D).
>>>
>>> I also found the Component.prepareImage() and Component.checkImage() 
>>> methods which also take an ImageObserver.  Those methods imply that 
>>> they will possibly start the process and return information on a 
>>> particular version of an image appropriate for the current output 
>>> device.  There is even a prepareImage(w,h) method that gets an image 
>>> ready to render at the indicated size.  Given that these methods are 
>>> on component, it probably makes sense to have that code look up 
>>> which representation would be used for those indicated dimensions on 
>>> the indicated output device that the Component is displayed on.
>>>
>>>              ...jim
>>>



More information about the macosx-port-dev mailing list