Add lockHardwareWideColorGamutCanvas.
This patch adds a hidden API to return a hardware canvas with wide color gamut support. The hardware canvas returned from BaseSurfaceHolder.lockHardwareCanvas doesn't support wide color gamut, this patch makes sure that a wide color gamut canvas context is created when calling lockHardwareCanvas. Verified this approach works by building ImageWallpaper to use this API. Without this API an 8 bit logo P3 doesn't show the logo, with this API the logo is shown correctly. See b/74116826 for more info. BUG: 74116826 Test: Build ImageWallpaper using this API with an 8 bit P3 image Change-Id: Id20343fabcd7f0873d79ce72a235ea9b7c1f3e77
This commit is contained in:
@@ -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 <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
|
||||
* unsupported drawing operations</a> 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);
|
||||
|
||||
@@ -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<RenderNode*>(rootNodePtr);
|
||||
sp<Surface> surface(reinterpret_cast<Surface*>(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 },
|
||||
|
||||
Reference in New Issue
Block a user