Enable WCG support for ImageWallpaper
Check if the system wallpaper is wcg and request a wcg surface if yes.
Also take multiple display case into account.
Bug: 136338733
Bug: 74008618
Test: Manually
Change-Id: I830dca97be61401453dffb892a7beb8afc0a32f4
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 41604ec..0c9fb2a 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -33,6 +33,7 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
@@ -40,6 +41,8 @@
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.ColorSpace;
+import android.graphics.ImageDecoder;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -63,11 +66,15 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
+import android.view.Display;
import android.view.WindowManagerGlobal;
+import com.android.internal.R;
+
import libcore.io.IoUtils;
import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -76,7 +83,10 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -193,7 +203,13 @@
*/
public static final int FLAG_LOCK = 1 << 1;
+ private static final Object sSync = new Object[0];
+ @UnsupportedAppUsage
+ private static Globals sGlobals;
+
private final Context mContext;
+ private final boolean mWcgEnabled;
+ private final ColorManagementProxy mCmProxy;
/**
* Special drawable that draws a wallpaper as fast as possible. Assumes
@@ -388,13 +404,14 @@
}
public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which) {
+ @SetWallpaperFlags int which, ColorManagementProxy cmProxy) {
return peekWallpaperBitmap(context, returnDefault, which, context.getUserId(),
- false /* hardware */);
+ false /* hardware */, cmProxy);
}
public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which, int userId, boolean hardware) {
+ @SetWallpaperFlags int which, int userId, boolean hardware,
+ ColorManagementProxy cmProxy) {
if (mService != null) {
try {
if (!mService.isWallpaperSupported(context.getOpPackageName())) {
@@ -412,7 +429,8 @@
mCachedWallpaper = null;
mCachedWallpaperUserId = 0;
try {
- mCachedWallpaper = getCurrentWallpaperLocked(context, userId, hardware);
+ mCachedWallpaper = getCurrentWallpaperLocked(
+ context, userId, hardware, cmProxy);
mCachedWallpaperUserId = userId;
} catch (OutOfMemoryError e) {
Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
@@ -450,7 +468,8 @@
}
}
- private Bitmap getCurrentWallpaperLocked(Context context, int userId, boolean hardware) {
+ private Bitmap getCurrentWallpaperLocked(Context context, int userId, boolean hardware,
+ ColorManagementProxy cmProxy) {
if (mService == null) {
Log.w(TAG, "WallpaperService not running");
return null;
@@ -458,21 +477,29 @@
try {
Bundle params = new Bundle();
- ParcelFileDescriptor fd = mService.getWallpaperWithFeature(
+ ParcelFileDescriptor pfd = mService.getWallpaperWithFeature(
context.getOpPackageName(), context.getFeatureId(), this, FLAG_SYSTEM,
params, userId);
- if (fd != null) {
- try {
- BitmapFactory.Options options = new BitmapFactory.Options();
- if (hardware) {
- options.inPreferredConfig = Bitmap.Config.HARDWARE;
+
+ if (pfd != null) {
+ try (BufferedInputStream bis = new BufferedInputStream(
+ new ParcelFileDescriptor.AutoCloseInputStream(pfd))) {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int data;
+ while ((data = bis.read()) != -1) {
+ baos.write(data);
}
- return BitmapFactory.decodeFileDescriptor(
- fd.getFileDescriptor(), null, options);
- } catch (OutOfMemoryError e) {
+ ImageDecoder.Source src = ImageDecoder.createSource(baos.toByteArray());
+ return ImageDecoder.decodeBitmap(src, ((decoder, info, source) -> {
+ // Mutable and hardware config can't be set at the same time.
+ decoder.setMutableRequired(!hardware);
+ // Let's do color management
+ if (cmProxy != null) {
+ cmProxy.doColorManagement(decoder, info);
+ }
+ }));
+ } catch (OutOfMemoryError | IOException e) {
Log.w(TAG, "Can't decode file", e);
- } finally {
- IoUtils.closeQuietly(fd);
}
}
} catch (RemoteException e) {
@@ -497,10 +524,6 @@
}
}
- private static final Object sSync = new Object[0];
- @UnsupportedAppUsage
- private static Globals sGlobals;
-
static void initGlobals(IWallpaperManager service, Looper looper) {
synchronized (sSync) {
if (sGlobals == null) {
@@ -514,6 +537,10 @@
if (service != null) {
initGlobals(service, context.getMainLooper());
}
+ // Check if supports mixed color spaces composition in hardware.
+ mWcgEnabled = context.getResources().getConfiguration().isScreenWideColorGamut()
+ && context.getResources().getBoolean(R.bool.config_enableWcgMode);
+ mCmProxy = new ColorManagementProxy(context);
}
/**
@@ -531,6 +558,22 @@
}
/**
+ * Indicate whether wcg (Wide Color Gamut) should be enabled.
+ * <p>
+ * Some devices lack of capability of mixed color spaces composition,
+ * enable wcg on such devices might cause memory or battery concern.
+ * <p>
+ * Therefore, in addition to {@link Configuration#isScreenWideColorGamut()},
+ * we also take mixed color spaces composition (config_enableWcgMode) into account.
+ *
+ * @see Configuration#isScreenWideColorGamut()
+ * @return True if wcg should be enabled for this device.
+ */
+ private boolean shouldEnableWideColorGamut() {
+ return mWcgEnabled;
+ }
+
+ /**
* Retrieve the current system wallpaper; if
* no wallpaper is set, the system built-in static wallpaper is returned.
* This is returned as an
@@ -546,7 +589,7 @@
* is not able to access the wallpaper.
*/
public Drawable getDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
dr.setDither(false);
@@ -777,7 +820,7 @@
* null pointer if these is none.
*/
public Drawable peekDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
dr.setDither(false);
@@ -801,7 +844,7 @@
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable getFastDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
return new FastBitmapDrawable(bm);
}
@@ -817,7 +860,7 @@
*/
@RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public Drawable peekFastDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, FLAG_SYSTEM, mCmProxy);
if (bm != null) {
return new FastBitmapDrawable(bm);
}
@@ -825,6 +868,27 @@
}
/**
+ * Whether the wallpaper supports Wide Color Gamut or not.
+ * @param which The wallpaper whose image file is to be retrieved. Must be a single
+ * defined kind of wallpaper, either {@link #FLAG_SYSTEM} or {@link #FLAG_LOCK}.
+ * @return true when supported.
+ *
+ * @see #FLAG_LOCK
+ * @see #FLAG_SYSTEM
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
+ public boolean wallpaperSupportsWcg(int which) {
+ if (!shouldEnableWideColorGamut()) {
+ return false;
+ }
+ Bitmap bitmap = sGlobals.peekWallpaperBitmap(mContext, false, which, mCmProxy);
+ return bitmap != null && bitmap.getColorSpace() != null
+ && bitmap.getColorSpace() != ColorSpace.get(ColorSpace.Named.SRGB)
+ && mCmProxy.isSupportedColorSpace(bitmap.getColorSpace());
+ }
+
+ /**
* Like {@link #getDrawable()} but returns a Bitmap with default {@link Bitmap.Config}.
*
* @hide
@@ -852,7 +916,8 @@
* @hide
*/
public Bitmap getBitmapAsUser(int userId, boolean hardware) {
- return sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, userId, hardware);
+ return sGlobals.peekWallpaperBitmap(
+ mContext, true, FLAG_SYSTEM, userId, hardware, mCmProxy);
}
/**
@@ -1975,6 +2040,33 @@
return false;
}
+ /**
+ * A private class to help Globals#getCurrentWallpaperLocked handle color management.
+ */
+ private static class ColorManagementProxy {
+ private final Set<ColorSpace> mSupportedColorSpaces = new HashSet<>();
+
+ ColorManagementProxy(Context context) {
+ // Get a list of supported wide gamut color spaces.
+ Display display = context.getDisplay();
+ if (display != null) {
+ mSupportedColorSpaces.addAll(Arrays.asList(display.getSupportedWideColorGamut()));
+ }
+ }
+
+ boolean isSupportedColorSpace(ColorSpace colorSpace) {
+ return colorSpace != null && (colorSpace == ColorSpace.get(ColorSpace.Named.SRGB)
+ || mSupportedColorSpaces.contains(colorSpace));
+ }
+
+ void doColorManagement(ImageDecoder decoder, ImageDecoder.ImageInfo info) {
+ if (!isSupportedColorSpace(info.getColorSpace())) {
+ decoder.setTargetColorSpace(ColorSpace.get(ColorSpace.Named.SRGB));
+ Log.w(TAG, "Not supported color space: " + info.getColorSpace());
+ }
+ }
+ }
+
// Private completion callback for setWallpaper() synchronization
private class WallpaperSetCompletion extends IWallpaperManagerCallback.Stub {
final CountDownLatch mLatch;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index ba25093..821bb25 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -43,7 +43,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
* Provides information about the size and density of a logical display.
@@ -382,6 +384,23 @@
/** @hide */
public static final int COLOR_MODE_DISPLAY_P3 = 9;
+ /** @hide **/
+ @IntDef(prefix = {"COLOR_MODE_"}, value = {
+ COLOR_MODE_INVALID,
+ COLOR_MODE_DEFAULT,
+ COLOR_MODE_BT601_625,
+ COLOR_MODE_BT601_625_UNADJUSTED,
+ COLOR_MODE_BT601_525,
+ COLOR_MODE_BT601_525_UNADJUSTED,
+ COLOR_MODE_BT709,
+ COLOR_MODE_DCI_P3,
+ COLOR_MODE_SRGB,
+ COLOR_MODE_ADOBE_RGB,
+ COLOR_MODE_DISPLAY_P3
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ColorMode {}
+
/**
* Indicates that when display is removed, all its activities will be moved to the primary
* display and the topmost activity should become focused.
@@ -960,6 +979,37 @@
}
/**
+ * Gets the supported wide color gamuts of this device.
+ *
+ * @return Supported WCG color spaces.
+ * @hide
+ */
+ public @ColorMode ColorSpace[] getSupportedWideColorGamut() {
+ synchronized (this) {
+ final ColorSpace[] defaultColorSpaces = new ColorSpace[0];
+ updateDisplayInfoLocked();
+ if (!isWideColorGamut()) {
+ return defaultColorSpaces;
+ }
+
+ final int[] colorModes = getSupportedColorModes();
+ final List<ColorSpace> colorSpaces = new ArrayList<>();
+ for (int colorMode : colorModes) {
+ // Refer to DisplayInfo#isWideColorGamut.
+ switch (colorMode) {
+ case COLOR_MODE_DCI_P3:
+ colorSpaces.add(ColorSpace.get(ColorSpace.Named.DCI_P3));
+ break;
+ case COLOR_MODE_DISPLAY_P3:
+ colorSpaces.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+ break;
+ }
+ }
+ return colorSpaces.toArray(defaultColorSpaces);
+ }
+ }
+
+ /**
* Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating
* the phase offset of the VSYNC events provided by Choreographer relative to the
* display refresh. For example, if Choreographer reports that the refresh occurred
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d6d5c57..a918940 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4248,6 +4248,10 @@
<!-- Add packages here -->
</string-array>
+ <!-- Whether or not wcg (wide color gamut) should be enabled on this device,
+ we only enabled it while the device has ability of mixed color spaces composition -->
+ <bool name="config_enableWcgMode">false</bool>
+
<!-- When true, enables the whitelisted app to handle bug reports from power menu short press. -->
<bool name="config_bugReportHandlerEnabled">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 011dc39..c1bebec 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3786,6 +3786,9 @@
<java-symbol type="string" name="accessibility_freeform_caption" />
+ <!-- For Wide Color Gamut -->
+ <java-symbol type="bool" name="config_enableWcgMode" />
+
<!-- For contacts provider. -->
<java-symbol type="string" name="config_rawContactsLocalAccountName" />
<java-symbol type="string" name="config_rawContactsLocalAccountType" />
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 29a71673..e50d08c 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -108,12 +108,13 @@
if (mController != null) {
mController.addCallback(this /* StateListener */);
}
- mEglHelper = new EglHelper();
- mRenderer = new ImageWallpaperRenderer(context, this /* SurfaceProxy */);
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
+ mEglHelper = new EglHelper();
+ // Deferred init renderer because we need to get wallpaper by display context.
+ mRenderer = new ImageWallpaperRenderer(getDisplayContext(), this /* SurfaceProxy */);
setFixedSizeAllowed(true);
setOffsetNotificationsEnabled(true);
updateSurfaceSize();
@@ -177,14 +178,13 @@
mRenderer = null;
mEglHelper.finish();
mEglHelper = null;
- getSurfaceHolder().getSurface().hwuiDestroy();
});
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
mWorker.getThreadHandler().post(() -> {
- mEglHelper.init(holder);
+ mEglHelper.init(holder, needSupportWideColorGamut());
mRenderer.onSurfaceCreated();
});
}
@@ -257,7 +257,7 @@
// Check if we need to recreate egl surface.
if (mEglHelper.hasEglContext() && !mEglHelper.hasEglSurface()) {
- if (!mEglHelper.createEglSurface(getSurfaceHolder())) {
+ if (!mEglHelper.createEglSurface(getSurfaceHolder(), needSupportWideColorGamut())) {
Log.w(TAG, "recreate egl surface failed!");
}
}
@@ -340,6 +340,10 @@
&& mController.getState() == StatusBarState.KEYGUARD;
}
+ private boolean needSupportWideColorGamut() {
+ return mRenderer.isWcgContent();
+ }
+
@Override
protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
super.dump(prefix, fd, out, args);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
index c6812a7..4b28540 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
@@ -51,40 +51,65 @@
import android.opengl.EGLDisplay;
import android.opengl.EGLSurface;
import android.opengl.GLUtils;
+import android.text.TextUtils;
import android.util.Log;
import android.view.SurfaceHolder;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
/**
* A helper class to handle EGL management.
*/
public class EglHelper {
private static final String TAG = EglHelper.class.getSimpleName();
+ private static final int OPENGLES_VERSION = 2;
// Below two constants make drawing at low priority, so other things can preempt our drawing.
private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
private static final boolean DEBUG = true;
+
+ private static final int EGL_GL_COLORSPACE_KHR = 0x309D;
+ private static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
+
private static final String EGL_IMG_CONTEXT_PRIORITY = "EGL_IMG_context_priority";
+ /**
+ * https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_gl_colorspace.txt
+ */
+ private static final String KHR_GL_COLOR_SPACE = "EGL_KHR_gl_colorspace";
+
+ /**
+ * https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3_passthrough.txt
+ */
+ private static final String EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH =
+ "EGL_EXT_gl_colorspace_display_p3_passthrough";
+
private EGLDisplay mEglDisplay;
private EGLConfig mEglConfig;
private EGLContext mEglContext;
private EGLSurface mEglSurface;
private final int[] mEglVersion = new int[2];
private boolean mEglReady;
- private boolean mContextPrioritySupported;
+ private final Set<String> mExts;
+
+ public EglHelper() {
+ mExts = new HashSet<>();
+ connectDisplay();
+ }
/**
- * Initialize EGL and prepare EglSurface.
+ * Initialize render context.
* @param surfaceHolder surface holder.
- * @return true if EglSurface is ready.
+ * @param wideColorGamut claim if a wcg surface is necessary.
+ * @return true if the render context is ready.
*/
- public boolean init(SurfaceHolder surfaceHolder) {
- mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (mEglDisplay == EGL_NO_DISPLAY) {
- Log.w(TAG, "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()));
+ public boolean init(SurfaceHolder surfaceHolder, boolean wideColorGamut) {
+ if (!hasEglDisplay() && !connectDisplay()) {
+ Log.w(TAG, "Can not connect display, abort!");
return false;
}
@@ -105,25 +130,38 @@
return false;
}
- if (!createEglSurface(surfaceHolder)) {
+ if (!createEglSurface(surfaceHolder, wideColorGamut)) {
Log.w(TAG, "Can't create EGLSurface!");
return false;
}
- mContextPrioritySupported = isContextPrioritySuppported();
-
mEglReady = true;
return true;
}
- private boolean isContextPrioritySuppported() {
- String[] extensions = eglQueryString(mEglDisplay, EGL_EXTENSIONS).split(" ");
- for (String extension : extensions) {
- if (extension.equals(EGL_IMG_CONTEXT_PRIORITY)) {
- return true;
- }
+ private boolean connectDisplay() {
+ mExts.clear();
+ mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!hasEglDisplay()) {
+ Log.w(TAG, "eglGetDisplay failed: " + GLUtils.getEGLErrorString(eglGetError()));
+ return false;
}
- return false;
+ String queryString = eglQueryString(mEglDisplay, EGL_EXTENSIONS);
+ if (!TextUtils.isEmpty(queryString)) {
+ Collections.addAll(mExts, queryString.split(" "));
+ }
+ return true;
+ }
+
+ private boolean checkExtensionCapability(String extName) {
+ return mExts.contains(extName);
+ }
+
+ private int getWcgCapability() {
+ if (checkExtensionCapability(EXT_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH)) {
+ return EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
+ }
+ return 0;
}
private EGLConfig chooseEglConfig() {
@@ -148,7 +186,7 @@
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 0,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
@@ -160,21 +198,27 @@
/**
* Prepare an EglSurface.
* @param surfaceHolder surface holder.
+ * @param wcg if need to support wcg.
* @return true if EglSurface is ready.
*/
- public boolean createEglSurface(SurfaceHolder surfaceHolder) {
+ public boolean createEglSurface(SurfaceHolder surfaceHolder, boolean wcg) {
if (DEBUG) {
Log.d(TAG, "createEglSurface start");
}
if (hasEglDisplay()) {
- mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null, 0);
+ int[] attrs = null;
+ int wcgCapability = getWcgCapability();
+ if (wcg && checkExtensionCapability(KHR_GL_COLOR_SPACE) && wcgCapability > 0) {
+ attrs = new int[] {EGL_GL_COLORSPACE_KHR, wcgCapability, EGL_NONE};
+ }
+ mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, attrs, 0);
} else {
Log.w(TAG, "mEglDisplay is null");
return false;
}
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+ if (!hasEglSurface()) {
Log.w(TAG, "createWindowSurface failed: " + GLUtils.getEGLErrorString(eglGetError()));
return false;
}
@@ -221,12 +265,12 @@
int[] attrib_list = new int[5];
int idx = 0;
attrib_list[idx++] = EGL_CONTEXT_CLIENT_VERSION;
- attrib_list[idx++] = 2;
- if (mContextPrioritySupported) {
+ attrib_list[idx++] = OPENGLES_VERSION;
+ if (checkExtensionCapability(EGL_IMG_CONTEXT_PRIORITY)) {
attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG;
attrib_list[idx++] = EGL_CONTEXT_PRIORITY_LOW_IMG;
}
- attrib_list[idx++] = EGL_NONE;
+ attrib_list[idx] = EGL_NONE;
if (hasEglDisplay()) {
mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0);
} else {
@@ -234,7 +278,7 @@
return false;
}
- if (mEglContext == EGL_NO_CONTEXT) {
+ if (!hasEglContext()) {
Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()));
return false;
}
@@ -260,7 +304,7 @@
* @return true if EglContext is ready.
*/
public boolean hasEglContext() {
- return mEglContext != null;
+ return mEglContext != null && mEglContext != EGL_NO_CONTEXT;
}
/**
@@ -268,7 +312,7 @@
* @return true if EglDisplay is ready.
*/
public boolean hasEglDisplay() {
- return mEglDisplay != null;
+ return mEglDisplay != null && mEglDisplay != EGL_NO_DISPLAY;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index 60ea1cdf..88ab9ef4 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -27,6 +27,11 @@
public interface GLWallpaperRenderer {
/**
+ * Check if the content to render is a WCG content.
+ */
+ boolean isWcgContent();
+
+ /**
* Called when the surface is created or recreated.
*/
void onSurfaceCreated();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 24a4b9e..54eca0e 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -116,7 +116,8 @@
int width = bitmap.getWidth();
int height = bitmap.getHeight();
- Bitmap grayscale = Bitmap.createBitmap(width, height, bitmap.getConfig());
+ Bitmap grayscale = Bitmap.createBitmap(width, height, bitmap.getConfig(),
+ false /* hasAlpha */, bitmap.getColorSpace());
Canvas canvas = new Canvas(grayscale);
ColorMatrix cm = new ColorMatrix(LUMINOSITY_MATRIX);
Paint paint = new Paint();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index a8371e3..fa8269d 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -62,6 +62,7 @@
private boolean mScissorMode;
private float mXOffset;
private float mYOffset;
+ private boolean mWcgContent;
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -94,6 +95,11 @@
}
@Override
+ public boolean isWcgContent() {
+ return mWcgContent;
+ }
+
+ @Override
public void onSurfaceCreated() {
glClearColor(0f, 0f, 0f, 1.0f);
mProgram.useGLProgram(
@@ -112,7 +118,8 @@
Log.d(TAG, "loadBitmap: mBitmap=" + mBitmap);
}
if (mWallpaperManager != null && mBitmap == null) {
- mBitmap = mWallpaperManager.getBitmap();
+ mBitmap = mWallpaperManager.getBitmap(false /* hardware */);
+ mWcgContent = mWallpaperManager.wallpaperSupportsWcg(WallpaperManager.FLAG_SYSTEM);
mWallpaperManager.forgetLoadedWallpaper();
if (mBitmap != null) {
float scale = (float) mScissor.height() / mBitmap.getHeight();
@@ -231,6 +238,7 @@
out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
out.print(prefix); out.print("mReveal="); out.print(mImageRevealHelper.getReveal());
+ out.print(prefix); out.print("mWcgContent="); out.print(mWcgContent);
mWallpaper.dump(prefix, fd, out, args);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
index b4a60d6..a5722e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java
@@ -52,7 +52,7 @@
@Test
public void testInit_finish() {
- mEglHelper.init(mSurfaceHolder);
+ mEglHelper.init(mSurfaceHolder, false /* wideColorGamut */);
mEglHelper.finish();
}