diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 8830c90addacd..d3b1e5c52596a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -396,7 +396,44 @@ public class Surface implements Parcelable {
synchronized (mLock) {
checkNotReleasedLocked();
if (mHwuiContext == null) {
- mHwuiContext = new HwuiContext();
+ mHwuiContext = new HwuiContext(false);
+ }
+ return mHwuiContext.lockCanvas(
+ nativeGetWidth(mNativeObject),
+ nativeGetHeight(mNativeObject));
+ }
+ }
+
+ /**
+ * Gets a {@link Canvas} for drawing into this surface that supports wide color gamut.
+ *
+ * After drawing into the provided {@link Canvas}, the caller must
+ * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
+ *
+ * Unlike {@link #lockCanvas(Rect)} and {@link #lockHardwareCanvas()},
+ * this will return a hardware-accelerated canvas that supports wide color gamut.
+ * See the
+ * unsupported drawing operations for a list of what is and isn't
+ * supported in a hardware-accelerated canvas. It is also required to
+ * fully cover the surface every time {@link #lockHardwareCanvas()} is
+ * called as the buffer is not preserved between frames. Partial updates
+ * are not supported.
+ *
+ * @return A canvas for drawing into the surface.
+ *
+ * @throws IllegalStateException If the canvas cannot be locked.
+ *
+ * @hide
+ */
+ public Canvas lockHardwareWideColorGamutCanvas() {
+ synchronized (mLock) {
+ checkNotReleasedLocked();
+ if (mHwuiContext != null && !mHwuiContext.isWideColorGamut()) {
+ mHwuiContext.destroy();
+ mHwuiContext = null;
+ }
+ if (mHwuiContext == null) {
+ mHwuiContext = new HwuiContext(true);
}
return mHwuiContext.lockCanvas(
nativeGetWidth(mNativeObject),
@@ -829,11 +866,14 @@ public class Surface implements Parcelable {
private final RenderNode mRenderNode;
private long mHwuiRenderer;
private DisplayListCanvas mCanvas;
+ private final boolean mIsWideColorGamut;
- HwuiContext() {
+ HwuiContext(boolean isWideColorGamut) {
mRenderNode = RenderNode.create("HwuiCanvas", null);
mRenderNode.setClipToBounds(false);
- mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject);
+ mIsWideColorGamut = isWideColorGamut;
+ mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject,
+ isWideColorGamut);
}
Canvas lockCanvas(int width, int height) {
@@ -864,9 +904,13 @@ public class Surface implements Parcelable {
mHwuiRenderer = 0;
}
}
+
+ boolean isWideColorGamut() {
+ return mIsWideColorGamut;
+ }
}
- private static native long nHwuiCreate(long rootNode, long surface);
+ private static native long nHwuiCreate(long rootNode, long surface, boolean isWideColorGamut);
private static native void nHwuiSetSurface(long renderer, long surface);
private static native void nHwuiDraw(long renderer);
private static native void nHwuiDestroy(long renderer);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f5c09fd316de9..f70cf07b9535f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -546,12 +546,16 @@ public:
}
};
-static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfacePtr) {
+static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfacePtr,
+ jboolean isWideColorGamut) {
RenderNode* rootNode = reinterpret_cast(rootNodePtr);
sp surface(reinterpret_cast(surfacePtr));
ContextFactory factory;
RenderProxy* proxy = new RenderProxy(false, rootNode, &factory);
proxy->loadSystemProperties();
+ if (isWideColorGamut) {
+ proxy->setWideGamut(true);
+ }
proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
proxy->initialize(surface);
// Shadows can't be used via this interface, so just set the light source
@@ -620,7 +624,7 @@ static const JNINativeMethod gSurfaceMethods[] = {
{"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
// HWUI context
- {"nHwuiCreate", "(JJ)J", (void*) hwui::create },
+ {"nHwuiCreate", "(JJZ)J", (void*) hwui::create },
{"nHwuiSetSurface", "(JJ)V", (void*) hwui::setSurface },
{"nHwuiDraw", "(J)V", (void*) hwui::draw },
{"nHwuiDestroy", "(J)V", (void*) hwui::destroy },