Short fix description:

The fix changes the initialization of the built-in color profiles/spaces from 
the lazy initialization per requested profile via static synchronization to the 
lazy initialization of all profiles/spaces on the first request via class 
initialization(holder idiom).

Long fix description:

1. A long time ago the factory method ICC_Profile#getInstance() was a 
heavyweight method. For each requested profile it used the data of the icc 
file(ex: sRGB: 6kb and pycc: 200kb).
As a result, in our code, we have tried to skip this method as much as possible 
or delay its usage. But we found that we have to use it anyway during startup. 
So we implemented the deferral mechanic for the sRGB profile. When this profile 
is requested we did not read the data but return the stub that contained some 
known in advance properties, such as num of color components, etc. The icc data 
is used only if the user request some of it later -> in this case we "activate" 
the profile and drop the stub data.

2. Later we found that we may need some other profiles at startup, and the 
deferral mechanics was implemented for all profiles by the JDK-6793818. But 
profile activation was implemented as one step for all profiles at once, so if 
one profile such as sRGB was activated then the next profiles returned from the 
"ICC_Profile#getInstance" if not requested before was activated as well(used 
the icc file data).

3. The deferral mechanics were updated in the JDK-6986863. Now activation of 
one profile does not affect other profiles and as a result, the 
"ICC_Profile#getInstance" always returns the stubs of the requested profiles.

4. Each profile stub contains just a few lightweight objects, but still, use 
the heavyweight static synchronization to access/create it, see:
   
https://github.com/openjdk/jdk/blob/9d59dec200490f11bfc1c661b30f10c7edee3a6d/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java#L821
   Note that we have separate blocks for each profile("stub"). That looks an 
overkill.
   
5. Note that in theory, it is not necessary to create these stubs lazily, each 
stub is a ICC_Profile object and ProfileDeferralInfo object, so we can use them 
as static fields in the ICC_Profile class. But here that classes initialization 
order come to play -> it is a bad idea to refer to the ICC_ProfileRGB(a 
subclass of the ICC_Profile) in the static block of ICC_Profile class because 
this could cause a deadlock.

6. So this change merged initialization of all stubs to the one-step, still 
initialize stubs lazily, and maintains the singleton property.

-------------

Commit messages:
 - Update ColorSpace.java
 - Update ICC_Profile.java
 - Update ColorSpace.java
 - Update ICC_Profile.java
 - cleanup
 - cleanup
 - Clean CMSManager
 - Add the tests
 - Real lazy
 - Implementing DCL

Changes: https://git.openjdk.java.net/jdk/pull/2447/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=2447&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8261282
  Stats: 370 lines in 6 files changed: 171 ins; 151 del; 48 mod
  Patch: https://git.openjdk.java.net/jdk/pull/2447.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/2447/head:pull/2447

PR: https://git.openjdk.java.net/jdk/pull/2447

Reply via email to