diff options
author | 2023-01-30 20:46:20 +0000 | |
---|---|---|
committer | 2023-01-30 20:16:21 -0800 | |
commit | cca989f2b52725468464534f337ee55d01644fb3 (patch) | |
tree | 8074e961d844c305436150453110ca734c5b9baa | |
parent | d10c26ad4cd9ee27ce688fb9ae033e97e62cfa92 (diff) |
Revert "Created HardwareBufferRenderer to support rendering into..."
Revert submission 20579518-hardware_buffer_renderer
Reason for revert: The submission timing tracks with a major regression in CtsUiRenderingTestCases stability: https://screenshot.googleplex.com/3TxXCSP4xCZq7Zy.png and also some crash bugs, eg: https://b.corp.google.com/issues/264889058
Reverting to re-stabilize the tree
Reverted changes: /q/submissionid:20579518-hardware_buffer_renderer
Change-Id: I29f47da097257bdeaa963fccb9ad0dbe39ead063
30 files changed, 157 insertions, 1199 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index bca9913ff94e..eb1c7f5b7f01 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -15310,29 +15310,6 @@ package android.graphics { ctor @Deprecated public EmbossMaskFilter(float[], float, float, float); } - public class HardwareBufferRenderer implements java.lang.AutoCloseable { - ctor public HardwareBufferRenderer(@NonNull android.hardware.HardwareBuffer); - method public void close(); - method public boolean isClosed(); - method @NonNull public android.graphics.HardwareBufferRenderer.RenderRequest obtainRenderRequest(); - method public void setContentRoot(@Nullable android.graphics.RenderNode); - method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float); - method public void setLightSourceGeometry(float, float, @FloatRange(from=0.0f) float, @FloatRange(from=0.0f) float); - } - - public final class HardwareBufferRenderer.RenderRequest { - method public void draw(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.graphics.HardwareBufferRenderer.RenderResult>); - method @NonNull public android.graphics.HardwareBufferRenderer.RenderRequest setBufferTransform(int); - method @NonNull public android.graphics.HardwareBufferRenderer.RenderRequest setColorSpace(@Nullable android.graphics.ColorSpace); - } - - public static final class HardwareBufferRenderer.RenderResult { - method @NonNull public android.hardware.SyncFence getFence(); - method public int getStatus(); - field public static final int ERROR_UNKNOWN = 1; // 0x1 - field public static final int SUCCESS = 0; // 0x0 - } - public class HardwareRenderer { ctor public HardwareRenderer(); method public void clearContent(); diff --git a/core/java/android/hardware/SyncFence.java b/core/java/android/hardware/SyncFence.java index d6052cd4c67f..166001347bd4 100644 --- a/core/java/android/hardware/SyncFence.java +++ b/core/java/android/hardware/SyncFence.java @@ -87,8 +87,8 @@ public final class SyncFence implements AutoCloseable, Parcelable { // is well worth making. private final Runnable mCloser; - private SyncFence(int fileDescriptor) { - mNativePtr = nCreate(fileDescriptor); + private SyncFence(@NonNull ParcelFileDescriptor wrapped) { + mNativePtr = nCreate(wrapped.detachFd()); mCloser = sRegistry.registerNativeAllocation(this, mNativePtr); } @@ -136,26 +136,14 @@ public final class SyncFence implements AutoCloseable, Parcelable { } /** - * Create a new SyncFence wrapped around another {@link ParcelFileDescriptor}. By default, all - * method calls are delegated to the wrapped descriptor. This takes ownership of the - * {@link ParcelFileDescriptor}. + * Create a new SyncFence wrapped around another descriptor. By default, all method calls are + * delegated to the wrapped descriptor. * * @param wrapped The descriptor to be wrapped. * @hide */ public static @NonNull SyncFence create(@NonNull ParcelFileDescriptor wrapped) { - return new SyncFence(wrapped.detachFd()); - } - - /** - * Create a new SyncFence wrapped around another descriptor. The returned {@link SyncFence} - * instance takes ownership of the file descriptor. - * - * @param fileDescriptor The descriptor to be wrapped. - * @hide - */ - public static @NonNull SyncFence adopt(int fileDescriptor) { - return new SyncFence(fileDescriptor); + return new SyncFence(wrapped); } /** diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp index d7cbf74d421a..93ba23bfdf84 100644 --- a/core/jni/LayoutlibLoader.cpp +++ b/core/jni/LayoutlibLoader.cpp @@ -102,7 +102,6 @@ extern int register_android_view_KeyCharacterMap(JNIEnv* env); extern int register_android_view_KeyEvent(JNIEnv* env); extern int register_android_view_MotionEvent(JNIEnv* env); extern int register_android_view_ThreadedRenderer(JNIEnv* env); -extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env); extern int register_android_view_VelocityTracker(JNIEnv* env); extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env); diff --git a/graphics/java/android/graphics/HardwareBufferRenderer.java b/graphics/java/android/graphics/HardwareBufferRenderer.java deleted file mode 100644 index 361dc594f2c6..000000000000 --- a/graphics/java/android/graphics/HardwareBufferRenderer.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.graphics; - -import android.annotation.FloatRange; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.graphics.ColorSpace.Named; -import android.hardware.HardwareBuffer; -import android.hardware.SyncFence; -import android.view.SurfaceControl; - -import libcore.util.NativeAllocationRegistry; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.Executor; -import java.util.function.Consumer; - -/** - * <p>Creates an instance of a hardware-accelerated renderer. This is used to render a scene built - * from {@link RenderNode}s to an output {@link HardwareBuffer}. There can be as many - * HardwareBufferRenderer instances as desired.</p> - * - * <h3>Resources & lifecycle</h3> - * - * <p>All HardwareBufferRenderer and {@link HardwareRenderer} instances share a common render - * thread. Therefore HardwareBufferRenderer will share common resources and GPU utilization with - * hardware accelerated rendering initiated by the UI thread of an application. - * The render thread contains the GPU context & resources necessary to do GPU-accelerated - * rendering. As such, the first HardwareBufferRenderer created comes with the cost of also creating - * the associated GPU contexts, however each incremental HardwareBufferRenderer thereafter is fairly - * cheap. The expected usage is to have a HardwareBufferRenderer instance for every active {@link - * HardwareBuffer}.</p> - * - * This is useful in situations where a scene built with {@link RenderNode}s can be consumed - * directly by the system compositor through - * {@link SurfaceControl.Transaction#setBuffer(SurfaceControl, HardwareBuffer)}. - * - * HardwareBufferRenderer will never clear contents before each draw invocation so previous contents - * in the {@link HardwareBuffer} target will be preserved across renders. - */ -public class HardwareBufferRenderer implements AutoCloseable { - - private static final ColorSpace DEFAULT_COLORSPACE = ColorSpace.get(Named.SRGB); - - private static class HardwareBufferRendererHolder { - public static final NativeAllocationRegistry REGISTRY = - NativeAllocationRegistry.createMalloced( - HardwareBufferRenderer.class.getClassLoader(), nGetFinalizer()); - } - - private final HardwareBuffer mHardwareBuffer; - private final RenderRequest mRenderRequest; - private final RenderNode mRootNode; - private final Runnable mCleaner; - - private long mProxy; - - /** - * Creates a new instance of {@link HardwareBufferRenderer} with the provided {@link - * HardwareBuffer} as the output of the rendered scene. - */ - public HardwareBufferRenderer(@NonNull HardwareBuffer buffer) { - RenderNode rootNode = RenderNode.adopt(nCreateRootRenderNode()); - rootNode.setClipToBounds(false); - mProxy = nCreateHardwareBufferRenderer(buffer, rootNode.mNativeRenderNode); - mCleaner = HardwareBufferRendererHolder.REGISTRY.registerNativeAllocation(this, mProxy); - mRenderRequest = new RenderRequest(); - mRootNode = rootNode; - mHardwareBuffer = buffer; - } - - /** - * Sets the content root to render. It is not necessary to call this whenever the content - * recording changes. Any mutations to the RenderNode content, or any of the RenderNodes - * contained within the content node, will be applied whenever a new {@link RenderRequest} is - * issued via {@link #obtainRenderRequest()} and {@link RenderRequest#draw(Executor, - * Consumer)}. - * - * @param content The content to set as the root RenderNode. If null the content root is removed - * and the renderer will draw nothing. - */ - public void setContentRoot(@Nullable RenderNode content) { - RecordingCanvas canvas = mRootNode.beginRecording(); - if (content != null) { - canvas.drawRenderNode(content); - } - mRootNode.endRecording(); - } - - /** - * Returns a {@link RenderRequest} that can be used to render into the provided {@link - * HardwareBuffer}. This is used to synchronize the RenderNode content provided by {@link - * #setContentRoot(RenderNode)}. - * - * @return An instance of {@link RenderRequest}. The instance may be reused for every frame, so - * the caller should not hold onto it for longer than a single render request. - */ - @NonNull - public RenderRequest obtainRenderRequest() { - mRenderRequest.reset(); - return mRenderRequest; - } - - /** - * Returns if the {@link HardwareBufferRenderer} has already been closed. That is - * {@link HardwareBufferRenderer#close()} has been invoked. - * @return True if the {@link HardwareBufferRenderer} has been closed, false otherwise. - */ - public boolean isClosed() { - return mProxy == 0L; - } - - /** - * Releases the resources associated with this {@link HardwareBufferRenderer} instance. **Note** - * this does not call {@link HardwareBuffer#close()} on the provided {@link HardwareBuffer} - * instance - */ - @Override - public void close() { - // Note we explicitly call this only here to clean-up potential animator state - // This is not done as part of the NativeAllocationRegistry as it would invoke animator - // callbacks on the wrong thread - nDestroyRootRenderNode(mRootNode.mNativeRenderNode); - if (mProxy != 0L) { - mCleaner.run(); - mProxy = 0L; - } - } - - /** - * Sets the center of the light source. The light source point controls the directionality and - * shape of shadows rendered by RenderNode Z & elevation. - * - * <p>The light source should be setup both as part of initial configuration, and whenever - * the window moves to ensure the light source stays anchored in display space instead of in - * window space. - * - * <p>This must be set at least once along with {@link #setLightSourceAlpha(float, float)} - * before shadows will work. - * - * @param lightX The X position of the light source. If unsure, a reasonable default - * is 'displayWidth / 2f - windowLeft'. - * @param lightY The Y position of the light source. If unsure, a reasonable default - * is '0 - windowTop' - * @param lightZ The Z position of the light source. Must be >= 0. If unsure, a reasonable - * default is 600dp. - * @param lightRadius The radius of the light source. Smaller radius will have sharper edges, - * larger radius will have softer shadows. If unsure, a reasonable default is 800 dp. - */ - public void setLightSourceGeometry( - float lightX, - float lightY, - @FloatRange(from = 0f) float lightZ, - @FloatRange(from = 0f) float lightRadius - ) { - validateFinite(lightX, "lightX"); - validateFinite(lightY, "lightY"); - validatePositive(lightZ, "lightZ"); - validatePositive(lightRadius, "lightRadius"); - nSetLightGeometry(mProxy, lightX, lightY, lightZ, lightRadius); - } - - /** - * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow has max - * alpha, and ramps down from the values provided to zero. - * - * <p>These values are typically provided by the current theme, see - * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}. - * - * <p>This must be set at least once along with - * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work. - * - * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default - * is 0.039f. - * @param spotShadowAlpha The alpha for the spot shadow. If unsure, a reasonable default is - * 0.19f. - */ - public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambientShadowAlpha, - @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha) { - validateAlpha(ambientShadowAlpha, "ambientShadowAlpha"); - validateAlpha(spotShadowAlpha, "spotShadowAlpha"); - nSetLightAlpha(mProxy, ambientShadowAlpha, spotShadowAlpha); - } - - /** - * Class that contains data regarding the result of the render request. - * Consumers are to wait on the provided {@link SyncFence} before consuming the HardwareBuffer - * provided to {@link HardwareBufferRenderer} as well as verify that the status returned by - * {@link RenderResult#getStatus()} returns {@link RenderResult#SUCCESS}. - */ - public static final class RenderResult { - - /** - * Render request was completed successfully - */ - public static final int SUCCESS = 0; - - /** - * Render request failed with an unknown error - */ - public static final int ERROR_UNKNOWN = 1; - - /** @hide **/ - @IntDef(value = {SUCCESS, ERROR_UNKNOWN}) - @Retention(RetentionPolicy.SOURCE) - public @interface RenderResultStatus{} - - private final SyncFence mFence; - private final int mResultStatus; - - private RenderResult(@NonNull SyncFence fence, @RenderResultStatus int resultStatus) { - mFence = fence; - mResultStatus = resultStatus; - } - - @NonNull - public SyncFence getFence() { - return mFence; - } - - @RenderResultStatus - public int getStatus() { - return mResultStatus; - } - } - - /** - * Sets the parameters that can be used to control a render request for a {@link - * HardwareBufferRenderer}. This is not thread-safe and must not be held on to for longer than a - * single request. - */ - public final class RenderRequest { - - private ColorSpace mColorSpace = DEFAULT_COLORSPACE; - private int mTransform = SurfaceControl.BUFFER_TRANSFORM_IDENTITY; - - private RenderRequest() { } - - /** - * Syncs the RenderNode tree to the render thread and requests content to be drawn. This - * {@link RenderRequest} instance should no longer be used after calling this method. The - * system internally may reuse instances of {@link RenderRequest} to reduce allocation - * churn. - * - * @param executor Executor used to deliver callbacks - * @param renderCallback Callback invoked when rendering is complete. This includes a - * {@link RenderResult} that provides a {@link SyncFence} that should be waited upon for - * completion before consuming the rendered output in the provided {@link HardwareBuffer} - * instance. - * - * @throws IllegalStateException if attempt to draw is made when - * {@link HardwareBufferRenderer#isClosed()} returns true - */ - public void draw( - @NonNull Executor executor, - @NonNull Consumer<RenderResult> renderCallback - ) { - Consumer<RenderResult> wrapped = consumable -> executor.execute( - () -> renderCallback.accept(consumable)); - if (!isClosed()) { - nRender( - mProxy, - mTransform, - mHardwareBuffer.getWidth(), - mHardwareBuffer.getHeight(), - mColorSpace.getNativeInstance(), - wrapped); - } else { - throw new IllegalStateException("Attempt to draw with a HardwareBufferRenderer " - + "instance that has already been closed"); - } - } - - private void reset() { - mColorSpace = DEFAULT_COLORSPACE; - mTransform = SurfaceControl.BUFFER_TRANSFORM_IDENTITY; - } - - /** - * Configures the color space which the content should be rendered in. This affects - * how the framework will interpret the color at each pixel. The color space provided here - * must be non-null, RGB based and leverage an ICC parametric curve. The min/max values - * of the components should not reduce the numerical range compared to the previously - * assigned color space. If left unspecified, the default color space of SRGB will be used. - * - * @param colorSpace The color space the content should be rendered in. If null is provided - * the default of SRGB will be used. - */ - @NonNull - public RenderRequest setColorSpace(@Nullable ColorSpace colorSpace) { - if (colorSpace == null) { - mColorSpace = DEFAULT_COLORSPACE; - } else { - mColorSpace = colorSpace; - } - return this; - } - - /** - * Specifies a transform to be applied before content is rendered. This is useful - * for pre-rotating content for the current display orientation to increase performance - * of displaying the associated buffer. This transformation will also adjust the light - * source position for the specified rotation. - * @see SurfaceControl.Transaction#setBufferTransform(SurfaceControl, int) - */ - @NonNull - public RenderRequest setBufferTransform( - @SurfaceControl.BufferTransform int bufferTransform) { - boolean validTransform = bufferTransform == SurfaceControl.BUFFER_TRANSFORM_IDENTITY - || bufferTransform == SurfaceControl.BUFFER_TRANSFORM_ROTATE_90 - || bufferTransform == SurfaceControl.BUFFER_TRANSFORM_ROTATE_180 - || bufferTransform == SurfaceControl.BUFFER_TRANSFORM_ROTATE_270; - if (validTransform) { - mTransform = bufferTransform; - } else { - throw new IllegalArgumentException("Invalid transform provided, must be one of" - + "the SurfaceControl.BufferTransform values"); - } - return this; - } - } - - /** - * @hide - */ - /* package */ - static native int nRender(long renderer, int transform, int width, int height, long colorSpace, - Consumer<RenderResult> callback); - - private static native long nCreateRootRenderNode(); - - private static native void nDestroyRootRenderNode(long rootRenderNode); - - private static native long nCreateHardwareBufferRenderer(HardwareBuffer buffer, - long rootRenderNode); - - private static native void nSetLightGeometry(long bufferRenderer, float lightX, float lightY, - float lightZ, float radius); - - private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha, - float spotShadowAlpha); - - private static native long nGetFinalizer(); - - // Called by native - private static void invokeRenderCallback( - @NonNull Consumer<RenderResult> callback, - int fd, - int status - ) { - callback.accept(new RenderResult(SyncFence.adopt(fd), status)); - } - - private static void validateAlpha(float alpha, String argumentName) { - if (!(alpha >= 0.0f && alpha <= 1.0f)) { - throw new IllegalArgumentException(argumentName + " must be a valid alpha, " - + alpha + " is not in the range of 0.0f to 1.0f"); - } - } - - private static void validateFinite(float f, String argumentName) { - if (!Float.isFinite(f)) { - throw new IllegalArgumentException(argumentName + " must be finite, given=" + f); - } - } - - private static void validatePositive(float f, String argumentName) { - if (!(Float.isFinite(f) && f >= 0.0f)) { - throw new IllegalArgumentException(argumentName - + " must be a finite positive, given=" + f); - } - } -} diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index dd6c2bc326fd..d116ed828527 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -338,7 +338,6 @@ cc_defaults { "jni/android_util_PathParser.cpp", "jni/Bitmap.cpp", - "jni/HardwareBufferHelpers.cpp", "jni/BitmapFactory.cpp", "jni/ByteBufferStreamAdaptor.cpp", "jni/Camera.cpp", @@ -415,7 +414,6 @@ cc_defaults { "jni/AnimatedImageDrawable.cpp", "jni/android_graphics_TextureLayer.cpp", "jni/android_graphics_HardwareRenderer.cpp", - "jni/android_graphics_HardwareBufferRenderer.cpp", "jni/BitmapRegionDecoder.cpp", "jni/GIFMovie.cpp", "jni/GraphicsStatsService.cpp", diff --git a/libs/hwui/apex/jni_runtime.cpp b/libs/hwui/apex/jni_runtime.cpp index c509ed4dfd21..d07fc5d36ca5 100644 --- a/libs/hwui/apex/jni_runtime.cpp +++ b/libs/hwui/apex/jni_runtime.cpp @@ -84,7 +84,6 @@ extern int register_android_util_PathParser(JNIEnv* env); extern int register_android_view_DisplayListCanvas(JNIEnv* env); extern int register_android_view_RenderNode(JNIEnv* env); extern int register_android_view_ThreadedRenderer(JNIEnv* env); -extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env); #ifdef NDEBUG #define REG_JNI(name) { name } @@ -154,8 +153,6 @@ extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env); REG_JNI(register_android_util_PathParser), REG_JNI(register_android_view_RenderNode), REG_JNI(register_android_view_DisplayListCanvas), - REG_JNI(register_android_graphics_HardwareBufferRenderer), - REG_JNI(register_android_view_ThreadedRenderer), }; diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 10c287d1e07d..1f5a1d3362c7 100644 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -2,42 +2,49 @@ #define LOG_TAG "Bitmap" #include "Bitmap.h" -#include <hwui/Bitmap.h> -#include <hwui/Paint.h> - -#include "CreateJavaOutputStreamAdaptor.h" #include "Gainmap.h" #include "GraphicsJNI.h" -#include "HardwareBufferHelpers.h" #include "SkBitmap.h" #include "SkBlendMode.h" #include "SkCanvas.h" #include "SkColor.h" #include "SkColorSpace.h" #include "SkData.h" +#include "SkImageEncoder.h" #include "SkImageInfo.h" #include "SkPaint.h" +#include "SkPixelRef.h" #include "SkPixmap.h" #include "SkPoint.h" #include "SkRefCnt.h" #include "SkStream.h" #include "SkTypes.h" +#include "SkWebpEncoder.h" + + #include "android_nio_utils.h" +#include "CreateJavaOutputStreamAdaptor.h" +#include <hwui/Paint.h> +#include <hwui/Bitmap.h> +#include <utils/Color.h> #ifdef __ANDROID__ // Layoutlib does not support graphic buffer, parcel or render thread #include <android-base/unique_fd.h> #include <android/binder_parcel.h> #include <android/binder_parcel_jni.h> #include <android/binder_parcel_platform.h> +#include <android/binder_parcel_utils.h> +#include <private/android/AHardwareBufferHelpers.h> #include <cutils/ashmem.h> +#include <dlfcn.h> #include <renderthread/RenderProxy.h> #include <sys/mman.h> #endif #include <inttypes.h> #include <string.h> - #include <memory> +#include <string> #define DEBUG_PARCEL 0 @@ -1198,11 +1205,18 @@ static jobject Bitmap_copyPreserveInternalConfig(JNIEnv* env, jobject, jlong bit return createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false)); } +#ifdef __ANDROID__ // Layoutlib does not support graphic buffer +typedef AHardwareBuffer* (*AHB_from_HB)(JNIEnv*, jobject); +AHB_from_HB AHardwareBuffer_fromHardwareBuffer; + +typedef jobject (*AHB_to_HB)(JNIEnv*, AHardwareBuffer*); +AHB_to_HB AHardwareBuffer_toHardwareBuffer; +#endif + static jobject Bitmap_wrapHardwareBufferBitmap(JNIEnv* env, jobject, jobject hardwareBuffer, jlong colorSpacePtr) { #ifdef __ANDROID__ // Layoutlib does not support graphic buffer - AHardwareBuffer* buffer = uirenderer::HardwareBufferHelpers::AHardwareBuffer_fromHardwareBuffer( - env, hardwareBuffer); + AHardwareBuffer* buffer = AHardwareBuffer_fromHardwareBuffer(env, hardwareBuffer); sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, GraphicsJNI::getNativeColorSpace(colorSpacePtr)); if (!bitmap.get()) { @@ -1225,8 +1239,7 @@ static jobject Bitmap_getHardwareBuffer(JNIEnv* env, jobject, jlong bitmapPtr) { } Bitmap& bitmap = bitmapHandle->bitmap(); - return uirenderer::HardwareBufferHelpers::AHardwareBuffer_toHardwareBuffer( - env, bitmap.hardwareBuffer()); + return AHardwareBuffer_toHardwareBuffer(env, bitmap.hardwareBuffer()); #else return nullptr; #endif @@ -1334,7 +1347,18 @@ int register_android_graphics_Bitmap(JNIEnv* env) gBitmap_nativePtr = GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J"); gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V"); gBitmap_reinitMethodID = GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V"); - uirenderer::HardwareBufferHelpers::init(); + +#ifdef __ANDROID__ // Layoutlib does not support graphic buffer or parcel + void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE); + AHardwareBuffer_fromHardwareBuffer = + (AHB_from_HB)dlsym(handle_, "AHardwareBuffer_fromHardwareBuffer"); + LOG_ALWAYS_FATAL_IF(AHardwareBuffer_fromHardwareBuffer == nullptr, + "Failed to find required symbol AHardwareBuffer_fromHardwareBuffer!"); + + AHardwareBuffer_toHardwareBuffer = (AHB_to_HB)dlsym(handle_, "AHardwareBuffer_toHardwareBuffer"); + LOG_ALWAYS_FATAL_IF(AHardwareBuffer_toHardwareBuffer == nullptr, + " Failed to find required symbol AHardwareBuffer_toHardwareBuffer!"); +#endif return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods, NELEM(gBitmapMethods)); } diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h index 6b983c10bdca..2c556af8a639 100644 --- a/libs/hwui/jni/GraphicsJNI.h +++ b/libs/hwui/jni/GraphicsJNI.h @@ -2,18 +2,19 @@ #define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ #include <cutils/compiler.h> -#include <hwui/Bitmap.h> -#include <hwui/Canvas.h> -#include "BRDAllocator.h" #include "Bitmap.h" +#include "BRDAllocator.h" #include "SkBitmap.h" #include "SkCodec.h" -#include "SkColorSpace.h" -#include "SkMallocPixelRef.h" #include "SkPixelRef.h" +#include "SkMallocPixelRef.h" #include "SkPoint.h" #include "SkRect.h" +#include "SkColorSpace.h" +#include <hwui/Canvas.h> +#include <hwui/Bitmap.h> + #include "graphics_jni_helpers.h" class SkCanvas; @@ -332,26 +333,6 @@ private: int fLen; }; -class JGlobalRefHolder { -public: - JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {} - - virtual ~JGlobalRefHolder() { - GraphicsJNI::getJNIEnv()->DeleteGlobalRef(mObject); - mObject = nullptr; - } - - jobject object() { return mObject; } - JavaVM* vm() { return mVm; } - -private: - JGlobalRefHolder(const JGlobalRefHolder&) = delete; - void operator=(const JGlobalRefHolder&) = delete; - - JavaVM* mVm; - jobject mObject; -}; - void doThrowNPE(JNIEnv* env); void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument diff --git a/libs/hwui/jni/HardwareBufferHelpers.cpp b/libs/hwui/jni/HardwareBufferHelpers.cpp deleted file mode 100644 index 7e3f771b6b3d..000000000000 --- a/libs/hwui/jni/HardwareBufferHelpers.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "HardwareBufferHelpers.h" - -#include <dlfcn.h> -#include <log/log.h> - -#ifdef __ANDROID__ -typedef AHardwareBuffer* (*AHB_from_HB)(JNIEnv*, jobject); -typedef jobject (*AHB_to_HB)(JNIEnv*, AHardwareBuffer*); -static AHB_from_HB fromHardwareBuffer = nullptr; -static AHB_to_HB toHardwareBuffer = nullptr; -#endif - -void android::uirenderer::HardwareBufferHelpers::init() { -#ifdef __ANDROID__ // Layoutlib does not support graphic buffer or parcel - void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE); - fromHardwareBuffer = (AHB_from_HB)dlsym(handle_, "AHardwareBuffer_fromHardwareBuffer"); - LOG_ALWAYS_FATAL_IF(fromHardwareBuffer == nullptr, - "Failed to find required symbol AHardwareBuffer_fromHardwareBuffer!"); - - toHardwareBuffer = (AHB_to_HB)dlsym(handle_, "AHardwareBuffer_toHardwareBuffer"); - LOG_ALWAYS_FATAL_IF(toHardwareBuffer == nullptr, - " Failed to find required symbol AHardwareBuffer_toHardwareBuffer!"); -#endif -} - -AHardwareBuffer* android::uirenderer::HardwareBufferHelpers::AHardwareBuffer_fromHardwareBuffer( - JNIEnv* env, jobject hardwarebuffer) { -#ifdef __ANDROID__ - LOG_ALWAYS_FATAL_IF(fromHardwareBuffer == nullptr, - "Failed to find symbol AHardwareBuffer_fromHardwareBuffer, did you forget " - "to call HardwareBufferHelpers::init?"); - return fromHardwareBuffer(env, hardwarebuffer); -#else - ALOGE("ERROR attempting to invoke AHardwareBuffer_fromHardwareBuffer on non Android " - "configuration"); - return nullptr; -#endif -} - -jobject android::uirenderer::HardwareBufferHelpers::AHardwareBuffer_toHardwareBuffer( - JNIEnv* env, AHardwareBuffer* ahardwarebuffer) { -#ifdef __ANDROID__ - LOG_ALWAYS_FATAL_IF(toHardwareBuffer == nullptr, - "Failed to find symbol AHardwareBuffer_toHardwareBuffer, did you forget to " - "call HardwareBufferHelpers::init?"); - return toHardwareBuffer(env, ahardwarebuffer); -#else - ALOGE("ERROR attempting to invoke AHardwareBuffer_toHardwareBuffer on non Android " - "configuration"); - return nullptr; -#endif -}
\ No newline at end of file diff --git a/libs/hwui/jni/HardwareBufferHelpers.h b/libs/hwui/jni/HardwareBufferHelpers.h deleted file mode 100644 index 326babfb0b34..000000000000 --- a/libs/hwui/jni/HardwareBufferHelpers.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef HARDWAREBUFFER_JNI_HELPERS_H -#define HARDWAREBUFFER_JNI_HELPERS_H - -#include <android/bitmap.h> -#include <jni.h> - -namespace android { -namespace uirenderer { - -class HardwareBufferHelpers { -public: - static void init(); - static AHardwareBuffer* AHardwareBuffer_fromHardwareBuffer(JNIEnv*, jobject); - static jobject AHardwareBuffer_toHardwareBuffer(JNIEnv*, AHardwareBuffer*); - -private: - HardwareBufferHelpers() = default; // not to be instantiated -}; - -} // namespace uirenderer -} // namespace android - -#endif // HARDWAREBUFFER_JNI_HELPERS_H
\ No newline at end of file diff --git a/libs/hwui/jni/JvmErrorReporter.h b/libs/hwui/jni/JvmErrorReporter.h deleted file mode 100644 index 5e10b9d93275..000000000000 --- a/libs/hwui/jni/JvmErrorReporter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef JVMERRORREPORTER_H -#define JVMERRORREPORTER_H - -#include <TreeInfo.h> -#include <jni.h> -#include <nativehelper/JNIHelp.h> - -#include "GraphicsJNI.h" - -namespace android { -namespace uirenderer { - -class JvmErrorReporter : public android::uirenderer::ErrorHandler { -public: - JvmErrorReporter(JNIEnv* env) { env->GetJavaVM(&mVm); } - - virtual void onError(const std::string& message) override { - JNIEnv* env = GraphicsJNI::getJNIEnv(); - jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); - } - -private: - JavaVM* mVm; -}; - -} // namespace uirenderer -} // namespace android - -#endif // JVMERRORREPORTER_H diff --git a/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp deleted file mode 100644 index 4886fdd7ac67..000000000000 --- a/libs/hwui/jni/android_graphics_HardwareBufferRenderer.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#undef LOG_TAG -#define LOG_TAG "HardwareBufferRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - -#include <GraphicsJNI.h> -#include <RootRenderNode.h> -#include <TreeInfo.h> -#include <android-base/unique_fd.h> -#include <android/native_window.h> -#include <nativehelper/JNIPlatformHelp.h> -#include <renderthread/CanvasContext.h> -#include <renderthread/RenderProxy.h> -#include <renderthread/RenderThread.h> - -#include "HardwareBufferHelpers.h" -#include "JvmErrorReporter.h" - -namespace android { - -using namespace android::uirenderer; -using namespace android::uirenderer::renderthread; - -struct { - jclass clazz; - jmethodID invokeRenderCallback; -} gHardwareBufferRendererClassInfo; - -static RenderCallback createRenderCallback(JNIEnv* env, jobject releaseCallback) { - if (releaseCallback == nullptr) return nullptr; - - JavaVM* vm = nullptr; - LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); - auto globalCallbackRef = - std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(releaseCallback)); - return [globalCallbackRef](android::base::unique_fd&& fd, int status) { - GraphicsJNI::getJNIEnv()->CallStaticVoidMethod( - gHardwareBufferRendererClassInfo.clazz, - gHardwareBufferRendererClassInfo.invokeRenderCallback, globalCallbackRef->object(), - reinterpret_cast<jint>(fd.release()), reinterpret_cast<jint>(status)); - }; -} - -static long android_graphics_HardwareBufferRenderer_createRootNode(JNIEnv* env, jobject) { - auto* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env)); - node->incStrong(nullptr); - node->setName("RootRenderNode"); - return reinterpret_cast<jlong>(node); -} - -static void android_graphics_hardwareBufferRenderer_destroyRootNode(JNIEnv*, jobject, - jlong renderNodePtr) { - auto* node = reinterpret_cast<RootRenderNode*>(renderNodePtr); - node->destroy(); -} - -static long android_graphics_HardwareBufferRenderer_create(JNIEnv* env, jobject, jobject buffer, - jlong renderNodePtr) { - auto* hardwareBuffer = HardwareBufferHelpers::AHardwareBuffer_fromHardwareBuffer(env, buffer); - auto* rootRenderNode = reinterpret_cast<RootRenderNode*>(renderNodePtr); - ContextFactoryImpl factory(rootRenderNode); - auto* proxy = new RenderProxy(true, rootRenderNode, &factory); - proxy->setHardwareBuffer(hardwareBuffer); - return (jlong)proxy; -} - -static void HardwareBufferRenderer_destroy(jobject renderProxy) { - auto* proxy = reinterpret_cast<RenderProxy*>(renderProxy); - delete proxy; -} - -static SkMatrix createMatrixFromBufferTransform(SkScalar width, SkScalar height, int transform) { - auto matrix = SkMatrix(); - switch (transform) { - case ANATIVEWINDOW_TRANSFORM_ROTATE_90: - matrix.setRotate(90); - matrix.postTranslate(width, 0); - break; - case ANATIVEWINDOW_TRANSFORM_ROTATE_180: - matrix.setRotate(180); - matrix.postTranslate(width, height); - break; - case ANATIVEWINDOW_TRANSFORM_ROTATE_270: - matrix.setRotate(270); - matrix.postTranslate(0, width); - break; - default: - ALOGE("Invalid transform provided. Transform should be validated from" - "the java side. Leveraging identity transform as a fallback"); - [[fallthrough]]; - case ANATIVEWINDOW_TRANSFORM_IDENTITY: - break; - } - return matrix; -} - -static int android_graphics_HardwareBufferRenderer_render(JNIEnv* env, jobject, jobject renderProxy, - jint transform, jint width, jint height, - jlong colorspacePtr, jobject consumer) { - auto* proxy = reinterpret_cast<RenderProxy*>(renderProxy); - auto skWidth = static_cast<SkScalar>(width); - auto skHeight = static_cast<SkScalar>(height); - auto matrix = createMatrixFromBufferTransform(skWidth, skHeight, transform); - auto colorSpace = GraphicsJNI::getNativeColorSpace(colorspacePtr); - proxy->setHardwareBufferRenderParams( - HardwareBufferRenderParams(matrix, colorSpace, createRenderCallback(env, consumer))); - return proxy->syncAndDrawFrame(); -} - -static void android_graphics_HardwareBufferRenderer_setLightGeometry(JNIEnv*, jobject, - jobject renderProxyPtr, - jfloat lightX, jfloat lightY, - jfloat lightZ, - jfloat lightRadius) { - auto* proxy = reinterpret_cast<RenderProxy*>(renderProxyPtr); - proxy->setLightGeometry((Vector3){lightX, lightY, lightZ}, lightRadius); -} - -static void android_graphics_HardwareBufferRenderer_setLightAlpha(JNIEnv* env, jobject, - jobject renderProxyPtr, - jfloat ambientShadowAlpha, - jfloat spotShadowAlpha) { - auto* proxy = reinterpret_cast<RenderProxy*>(renderProxyPtr); - proxy->setLightAlpha((uint8_t)(255 * ambientShadowAlpha), (uint8_t)(255 * spotShadowAlpha)); -} - -static jlong android_graphics_HardwareBufferRenderer_getFinalizer() { - return static_cast<jlong>(reinterpret_cast<uintptr_t>(&HardwareBufferRenderer_destroy)); -} - -// ---------------------------------------------------------------------------- -// JNI Glue -// ---------------------------------------------------------------------------- - -const char* const kClassPathName = "android/graphics/HardwareBufferRenderer"; - -static const JNINativeMethod gMethods[] = { - {"nCreateHardwareBufferRenderer", "(Landroid/hardware/HardwareBuffer;J)J", - (void*)android_graphics_HardwareBufferRenderer_create}, - {"nRender", "(JIIIJLjava/util/function/Consumer;)I", - (void*)android_graphics_HardwareBufferRenderer_render}, - {"nCreateRootRenderNode", "()J", - (void*)android_graphics_HardwareBufferRenderer_createRootNode}, - {"nSetLightGeometry", "(JFFFF)V", - (void*)android_graphics_HardwareBufferRenderer_setLightGeometry}, - {"nSetLightAlpha", "(JFF)V", (void*)android_graphics_HardwareBufferRenderer_setLightAlpha}, - {"nGetFinalizer", "()J", (void*)android_graphics_HardwareBufferRenderer_getFinalizer}, - {"nDestroyRootRenderNode", "(J)V", - (void*)android_graphics_hardwareBufferRenderer_destroyRootNode}}; - -int register_android_graphics_HardwareBufferRenderer(JNIEnv* env) { - jclass hardwareBufferRendererClazz = - FindClassOrDie(env, "android/graphics/HardwareBufferRenderer"); - gHardwareBufferRendererClassInfo.clazz = hardwareBufferRendererClazz; - gHardwareBufferRendererClassInfo.invokeRenderCallback = - GetStaticMethodIDOrDie(env, hardwareBufferRendererClazz, "invokeRenderCallback", - "(Ljava/util/function/Consumer;II)V"); - HardwareBufferHelpers::init(); - return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); -} - -} // namespace android
\ No newline at end of file diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index d6aad7d3eede..a30fc496b2fd 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -56,7 +56,6 @@ #include <atomic> #include <vector> -#include "JvmErrorReporter.h" #include "android_graphics_HardwareRendererObserver.h" namespace android { @@ -94,12 +93,35 @@ struct { jmethodID getDestinationBitmap; } gCopyRequest; +static JNIEnv* getenv(JavaVM* vm) { + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { + LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm); + } + return env; +} + typedef ANativeWindow* (*ANW_fromSurface)(JNIEnv* env, jobject surface); ANW_fromSurface fromSurface; +class JvmErrorReporter : public ErrorHandler { +public: + JvmErrorReporter(JNIEnv* env) { + env->GetJavaVM(&mVm); + } + + virtual void onError(const std::string& message) override { + JNIEnv* env = getenv(mVm); + jniThrowException(env, "java/lang/IllegalStateException", message.c_str()); + } +private: + JavaVM* mVm; +}; + class FrameCommitWrapper : public LightRefBase<FrameCommitWrapper> { public: explicit FrameCommitWrapper(JNIEnv* env, jobject jobject) { + env->GetJavaVM(&mVm); mObject = env->NewGlobalRef(jobject); LOG_ALWAYS_FATAL_IF(!mObject, "Failed to make global ref"); } @@ -109,18 +131,19 @@ public: void onFrameCommit(bool didProduceBuffer) { if (mObject) { ATRACE_FORMAT("frameCommit success=%d", didProduceBuffer); - GraphicsJNI::getJNIEnv()->CallVoidMethod(mObject, gFrameCommitCallback.onFrameCommit, - didProduceBuffer); + getenv(mVm)->CallVoidMethod(mObject, gFrameCommitCallback.onFrameCommit, + didProduceBuffer); releaseObject(); } } private: + JavaVM* mVm; jobject mObject; void releaseObject() { if (mObject) { - GraphicsJNI::getJNIEnv()->DeleteGlobalRef(mObject); + getenv(mVm)->DeleteGlobalRef(mObject); mObject = nullptr; } } @@ -426,6 +449,26 @@ static void android_view_ThreadedRenderer_forceDrawNextFrame(JNIEnv* env, jobjec proxy->forceDrawNextFrame(); } +class JGlobalRefHolder { +public: + JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {} + + virtual ~JGlobalRefHolder() { + getenv(mVm)->DeleteGlobalRef(mObject); + mObject = nullptr; + } + + jobject object() { return mObject; } + JavaVM* vm() { return mVm; } + +private: + JGlobalRefHolder(const JGlobalRefHolder&) = delete; + void operator=(const JGlobalRefHolder&) = delete; + + JavaVM* mVm; + jobject mObject; +}; + using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>; struct PictureCaptureState { @@ -541,7 +584,7 @@ static void android_view_ThreadedRenderer_setPictureCapturedCallbackJNI(JNIEnv* auto pictureState = std::make_shared<PictureCaptureState>(); proxy->setPictureCapturedCallback([globalCallbackRef, pictureState](sk_sp<SkPicture>&& picture) { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(globalCallbackRef->vm()); Picture* wrapper = new PictureWrapper{std::move(picture), pictureState}; env->CallStaticVoidMethod(gHardwareRenderer.clazz, gHardwareRenderer.invokePictureCapturedCallback, @@ -563,7 +606,7 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( vm, env->NewGlobalRef(aSurfaceTransactionCallback)); proxy->setASurfaceTransactionCallback( [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) -> bool { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(globalCallbackRef->vm()); jboolean ret = env->CallBooleanMethod( globalCallbackRef->object(), gASurfaceTransactionCallback.onMergeTransaction, @@ -585,7 +628,7 @@ static void android_view_ThreadedRenderer_setPrepareSurfaceControlForWebviewCall auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); proxy->setPrepareSurfaceControlForWebviewCallback([globalCallbackRef]() { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(globalCallbackRef->vm()); env->CallVoidMethod(globalCallbackRef->object(), gPrepareSurfaceControlForWebviewCallback.prepare); }); @@ -604,7 +647,7 @@ static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env, env->NewGlobalRef(frameCallback)); proxy->setFrameCallback([globalCallbackRef](int32_t syncResult, int64_t frameNr) -> std::function<void(bool)> { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(globalCallbackRef->vm()); ScopedLocalRef<jobject> frameCommitCallback( env, env->CallObjectMethod( globalCallbackRef->object(), gFrameDrawingCallback.onFrameDraw, @@ -643,7 +686,7 @@ static void android_view_ThreadedRenderer_setFrameCompleteCallback(JNIEnv* env, auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); proxy->setFrameCompleteCallback([globalCallbackRef]() { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(globalCallbackRef->vm()); env->CallVoidMethod(globalCallbackRef->object(), gFrameCompleteCallback.onFrameComplete); }); @@ -656,7 +699,7 @@ public: : CopyRequest(srcRect), mRefHolder(vm, jCopyRequest) {} virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(mRefHolder.vm()); jlong bitmapPtr = env->CallLongMethod( mRefHolder.object(), gCopyRequest.getDestinationBitmap, srcWidth, srcHeight); SkBitmap bitmap; @@ -665,7 +708,7 @@ public: } virtual void onCopyFinished(CopyResult result) override { - JNIEnv* env = GraphicsJNI::getJNIEnv(); + JNIEnv* env = getenv(mRefHolder.vm()); env->CallVoidMethod(mRefHolder.object(), gCopyRequest.onCopyFinished, static_cast<jint>(result)); } diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index 202a62cf320c..19cd7bdd6fcb 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -55,9 +55,7 @@ SkiaOpenGLPipeline::~SkiaOpenGLPipeline() { MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() { // In case the surface was destroyed (e.g. a previous trimMemory call) we // need to recreate it here. - if (mHardwareBuffer) { - mRenderThread.requireGlContext(); - } else if (!isSurfaceReady() && mNativeWindow) { + if (!isSurfaceReady() && mNativeWindow) { setSurface(mNativeWindow.get(), mSwapBehavior); } @@ -69,24 +67,17 @@ MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() { } Frame SkiaOpenGLPipeline::getFrame() { - if (mHardwareBuffer) { - AHardwareBuffer_Desc description; - AHardwareBuffer_describe(mHardwareBuffer, &description); - return Frame(description.width, description.height, 0); - } else { - LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, - "drawRenderNode called on a context with no surface!"); - return mEglManager.beginFrame(mEglSurface); - } + LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE, + "drawRenderNode called on a context with no surface!"); + return mEglManager.beginFrame(mEglSurface); } IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw( const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo, - const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler, - const HardwareBufferRenderParams& bufferParams) { - if (!isCapturingSkp() && !mHardwareBuffer) { + const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { + if (!isCapturingSkp()) { mEglManager.damageFrame(frame, dirty); } @@ -113,25 +104,13 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw( SkSurfaceProps props(0, kUnknown_SkPixelGeometry); SkASSERT(mRenderThread.getGrContext() != nullptr); - sk_sp<SkSurface> surface; - SkMatrix preTransform; - if (mHardwareBuffer) { - surface = getBufferSkSurface(bufferParams); - preTransform = bufferParams.getTransform(); - } else { - surface = SkSurface::MakeFromBackendRenderTarget(mRenderThread.getGrContext(), backendRT, - getSurfaceOrigin(), colorType, - mSurfaceColorSpace, &props); - preTransform = SkMatrix::I(); - } + sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget( + mRenderThread.getGrContext(), backendRT, this->getSurfaceOrigin(), colorType, + mSurfaceColorSpace, &props)); - SkPoint lightCenter = preTransform.mapXY(lightGeometry.center.x, lightGeometry.center.y); - LightGeometry localGeometry = lightGeometry; - localGeometry.center.x = lightCenter.fX; - localGeometry.center.y = lightCenter.fY; - LightingInfo::updateLighting(localGeometry, lightInfo); + LightingInfo::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface, - preTransform); + SkMatrix::I()); // Draw visual debugging features if (CC_UNLIKELY(Properties::showDirtyRegions || @@ -163,10 +142,6 @@ bool SkiaOpenGLPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect // metrics the frame was swapped at this point currentFrameInfo->markSwapBuffers(); - if (mHardwareBuffer) { - return false; - } - *requireSwap = drew || mEglManager.damageRequiresSwap(); if (*requireSwap && (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty)))) { @@ -222,26 +197,6 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh return false; } -[[nodiscard]] android::base::unique_fd SkiaOpenGLPipeline::flush() { - int fence = -1; - EGLSyncKHR sync = EGL_NO_SYNC_KHR; - mEglManager.createReleaseFence(true, &sync, &fence); - // If a sync object is returned here then the device does not support native - // fences, we block on the returned sync and return -1 as a file descriptor - if (sync != EGL_NO_SYNC_KHR) { - EGLDisplay display = mEglManager.eglDisplay(); - EGLint result = eglClientWaitSyncKHR(display, sync, 0, 1000000000); - if (result == EGL_FALSE) { - ALOGE("EglManager::createReleaseFence: error waiting for previous fence: %#x", - eglGetError()); - } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { - ALOGE("EglManager::createReleaseFence: timeout waiting for previous fence"); - } - eglDestroySyncKHR(display, sync); - } - return android::base::unique_fd(fence); -} - bool SkiaOpenGLPipeline::isSurfaceReady() { return CC_UNLIKELY(mEglSurface != EGL_NO_SURFACE); } diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h index 940d6bfdb83c..a80c613697f2 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h @@ -21,7 +21,6 @@ #include "SkiaPipeline.h" #include "renderstate/RenderState.h" -#include "renderthread/HardwareBufferRenderParams.h" namespace android { @@ -37,18 +36,19 @@ public: renderthread::MakeCurrentResult makeCurrent() override; renderthread::Frame getFrame() override; - renderthread::IRenderPipeline::DrawResult draw( - const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty, - const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo, - const std::vector<sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler, - const renderthread::HardwareBufferRenderParams& bufferParams) override; + renderthread::IRenderPipeline::DrawResult draw(const renderthread::Frame& frame, + const SkRect& screenDirty, const SkRect& dirty, + const LightGeometry& lightGeometry, + LayerUpdateQueue* layerUpdateQueue, + const Rect& contentDrawBounds, bool opaque, + const LightInfo& lightInfo, + const std::vector<sp<RenderNode> >& renderNodes, + FrameInfoVisualizer* profiler) override; GrSurfaceOrigin getSurfaceOrigin() override { return kBottomLeft_GrSurfaceOrigin; } bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) override; DeferredLayerUpdater* createTextureLayer() override; bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override; - [[nodiscard]] android::base::unique_fd flush() override; void onStop() override; bool isSurfaceReady() override; bool isContextReady() override; diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 2017eb6eb7da..09c3120a9f71 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -605,31 +605,6 @@ void SkiaPipeline::dumpResourceCacheUsage() const { ALOGD("%s", log.c_str()); } -void SkiaPipeline::setHardwareBuffer(AHardwareBuffer* buffer) { - if (mHardwareBuffer) { - AHardwareBuffer_release(mHardwareBuffer); - mHardwareBuffer = nullptr; - } - - if (buffer) { - AHardwareBuffer_acquire(buffer); - mHardwareBuffer = buffer; - } -} - -sk_sp<SkSurface> SkiaPipeline::getBufferSkSurface( - const renderthread::HardwareBufferRenderParams& bufferParams) { - auto bufferColorSpace = bufferParams.getColorSpace(); - if (mBufferSurface == nullptr || mBufferColorSpace == nullptr || - !SkColorSpace::Equals(mBufferColorSpace.get(), bufferColorSpace.get())) { - mBufferSurface = SkSurface::MakeFromAHardwareBuffer( - mRenderThread.getGrContext(), mHardwareBuffer, kTopLeft_GrSurfaceOrigin, - bufferColorSpace, nullptr, true); - mBufferColorSpace = bufferColorSpace; - } - return mBufferSurface; -} - void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) { mColorMode = colorMode; switch (colorMode) { diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index befee8989383..b7d799f705b3 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -20,11 +20,9 @@ #include <SkDocument.h> #include <SkMultiPictureDocument.h> #include <SkSurface.h> - #include "Lighting.h" #include "hwui/AnimatedImageDrawable.h" #include "renderthread/CanvasContext.h" -#include "renderthread/HardwareBufferRenderParams.h" #include "renderthread/IRenderPipeline.h" class SkFILEWStream; @@ -75,22 +73,14 @@ public: mCaptureMode = callback ? CaptureMode::CallbackAPI : CaptureMode::None; } - virtual void setHardwareBuffer(AHardwareBuffer* buffer) override; - bool hasHardwareBuffer() override { return mHardwareBuffer != nullptr; } void setTargetSdrHdrRatio(float ratio) override; protected: - sk_sp<SkSurface> getBufferSkSurface( - const renderthread::HardwareBufferRenderParams& bufferParams); void dumpResourceCacheUsage() const; renderthread::RenderThread& mRenderThread; - AHardwareBuffer* mHardwareBuffer = nullptr; - sk_sp<SkSurface> mBufferSurface = nullptr; - sk_sp<SkColorSpace> mBufferColorSpace = nullptr; - ColorMode mColorMode = ColorMode::Default; SkColorType mSurfaceColorType; sk_sp<SkColorSpace> mSurfaceColorSpace; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 99298bc0fe9b..a8c752f0e0b7 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -57,55 +57,37 @@ VulkanManager& SkiaVulkanPipeline::vulkanManager() { MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { // In case the surface was destroyed (e.g. a previous trimMemory call) we // need to recreate it here. - if (mHardwareBuffer) { - mRenderThread.requireVkContext(); - } else if (!isSurfaceReady() && mNativeWindow) { + if (!isSurfaceReady() && mNativeWindow) { setSurface(mNativeWindow.get(), SwapBehavior::kSwap_default); } return isContextReady() ? MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed; } Frame SkiaVulkanPipeline::getFrame() { - if (mHardwareBuffer) { - AHardwareBuffer_Desc description; - AHardwareBuffer_describe(mHardwareBuffer, &description); - return Frame(description.width, description.height, 0); - } else { - LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, - "getFrame() called on a context with no surface!"); - return vulkanManager().dequeueNextBuffer(mVkSurface); - } + LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "getFrame() called on a context with no surface!"); + return vulkanManager().dequeueNextBuffer(mVkSurface); } IRenderPipeline::DrawResult SkiaVulkanPipeline::draw( const Frame& frame, const SkRect& screenDirty, const SkRect& dirty, const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo, - const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler, - const HardwareBufferRenderParams& bufferParams) { - sk_sp<SkSurface> backBuffer; - SkMatrix preTransform; - if (mHardwareBuffer) { - backBuffer = getBufferSkSurface(bufferParams); - preTransform = bufferParams.getTransform(); - } else { - backBuffer = mVkSurface->getCurrentSkSurface(); - preTransform = mVkSurface->getCurrentPreTransform(); - } - + const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { + sk_sp<SkSurface> backBuffer = mVkSurface->getCurrentSkSurface(); if (backBuffer.get() == nullptr) { return {false, -1}; } // update the coordinates of the global light position based on surface rotation - SkPoint lightCenter = preTransform.mapXY(lightGeometry.center.x, lightGeometry.center.y); + SkPoint lightCenter = mVkSurface->getCurrentPreTransform().mapXY(lightGeometry.center.x, + lightGeometry.center.y); LightGeometry localGeometry = lightGeometry; localGeometry.center.x = lightCenter.fX; localGeometry.center.y = lightCenter.fY; LightingInfo::updateLighting(localGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer, - preTransform); + mVkSurface->getCurrentPreTransform()); // Draw visual debugging features if (CC_UNLIKELY(Properties::showDirtyRegions || @@ -134,16 +116,12 @@ IRenderPipeline::DrawResult SkiaVulkanPipeline::draw( bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) { + *requireSwap = drew; + // Even if we decided to cancel the frame, from the perspective of jank // metrics the frame was swapped at this point currentFrameInfo->markSwapBuffers(); - if (mHardwareBuffer) { - return false; - } - - *requireSwap = drew; - if (*requireSwap) { vulkanManager().swapBuffers(mVkSurface, screenDirty); } @@ -159,12 +137,6 @@ DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { void SkiaVulkanPipeline::onStop() {} -[[nodiscard]] android::base::unique_fd SkiaVulkanPipeline::flush() { - int fence = -1; - vulkanManager().createReleaseFence(&fence, mRenderThread.getGrContext()); - return android::base::unique_fd(fence); -} - // We can safely ignore the swap behavior because VkManager will always operate // in a mode equivalent to EGLManager::SwapBehavior::kBufferAge bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior /*swapBehavior*/) { diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index d921ddb0d0fb..e0884a8390a6 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -16,13 +16,14 @@ #pragma once -#include "SkRefCnt.h" #include "SkiaPipeline.h" -#include "renderstate/RenderState.h" -#include "renderthread/HardwareBufferRenderParams.h" #include "renderthread/VulkanManager.h" #include "renderthread/VulkanSurface.h" +#include "renderstate/RenderState.h" + +#include "SkRefCnt.h" + class SkBitmap; struct SkRect; @@ -37,18 +38,18 @@ public: renderthread::MakeCurrentResult makeCurrent() override; renderthread::Frame getFrame() override; - renderthread::IRenderPipeline::DrawResult draw( - const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty, - const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, - const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo, - const std::vector<sp<RenderNode> >& renderNodes, FrameInfoVisualizer* profiler, - const renderthread::HardwareBufferRenderParams& bufferParams) override; + renderthread::IRenderPipeline::DrawResult draw(const renderthread::Frame& frame, + const SkRect& screenDirty, const SkRect& dirty, + const LightGeometry& lightGeometry, + LayerUpdateQueue* layerUpdateQueue, + const Rect& contentDrawBounds, bool opaque, + const LightInfo& lightInfo, + const std::vector<sp<RenderNode> >& renderNodes, + FrameInfoVisualizer* profiler) override; GrSurfaceOrigin getSurfaceOrigin() override { return kTopLeft_GrSurfaceOrigin; } bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) override; DeferredLayerUpdater* createTextureLayer() override; - [[nodiscard]] android::base::unique_fd flush() override; - bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override; void onStop() override; bool isSurfaceReady() override; @@ -65,6 +66,7 @@ protected: private: renderthread::VulkanManager& vulkanManager(); + renderthread::VulkanSurface* mVkSurface = nullptr; sp<ANativeWindow> mNativeWindow; }; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index ee1c2ec81a91..c0f30865d507 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -153,7 +153,6 @@ void CanvasContext::removeRenderNode(RenderNode* node) { void CanvasContext::destroy() { stopDrawing(); - setHardwareBuffer(nullptr); setSurface(nullptr); setSurfaceControl(nullptr); freePrefetchedLayers(); @@ -177,19 +176,6 @@ static void setBufferCount(ANativeWindow* window) { native_window_set_buffer_count(window, bufferCount); } -void CanvasContext::setHardwareBuffer(AHardwareBuffer* buffer) { - if (mHardwareBuffer) { - AHardwareBuffer_release(mHardwareBuffer); - mHardwareBuffer = nullptr; - } - - if (buffer) { - AHardwareBuffer_acquire(buffer); - mHardwareBuffer = buffer; - } - mRenderPipeline->setHardwareBuffer(mHardwareBuffer); -} - void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { ATRACE_CALL(); @@ -275,7 +261,7 @@ void CanvasContext::setStopped(bool stopped) { mRenderThread.removeFrameCallback(this); mRenderPipeline->onStop(); mRenderThread.cacheManager().onContextStopped(this); - } else if (mIsDirty && hasOutputTarget()) { + } else if (mIsDirty && hasSurface()) { mRenderThread.postFrameCallback(this); } } @@ -439,7 +425,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy mIsDirty = true; - if (CC_UNLIKELY(!hasOutputTarget())) { + if (CC_UNLIKELY(!hasSurface())) { mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); info.out.canDrawThisFrame = false; return; @@ -584,7 +570,7 @@ void CanvasContext::draw() { std::scoped_lock lock(mFrameMetricsReporterMutex); drawResult = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue, mContentDrawBounds, mOpaque, - mLightInfo, mRenderNodes, &(profiler()), mBufferParams); + mLightInfo, mRenderNodes, &(profiler())); } uint64_t frameCompleteNr = getFrameNumber(); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index a811670e8176..0f6b736e7edf 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -125,13 +125,12 @@ public: // Won't take effect until next EGLSurface creation void setSwapBehavior(SwapBehavior swapBehavior); - void setHardwareBuffer(AHardwareBuffer* buffer); void setSurface(ANativeWindow* window, bool enableTimeout = true); void setSurfaceControl(ASurfaceControl* surfaceControl); bool pauseSurface(); void setStopped(bool stopped); - bool isStopped() { return mStopped || !hasOutputTarget(); } - bool hasOutputTarget() const { return mNativeSurface.get() || mHardwareBuffer; } + bool isStopped() { return mStopped || !hasSurface(); } + bool hasSurface() const { return mNativeSurface.get(); } void allocateBuffers(); void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); @@ -209,10 +208,6 @@ public: mASurfaceTransactionCallback = callback; } - void setHardwareBufferRenderParams(const HardwareBufferRenderParams& params) { - mBufferParams = params; - } - bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control); void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback) { @@ -267,9 +262,6 @@ private: int32_t mLastFrameHeight = 0; RenderThread& mRenderThread; - - AHardwareBuffer* mHardwareBuffer = nullptr; - HardwareBufferRenderParams mBufferParams; std::unique_ptr<ReliableSurface> mNativeSurface; // The SurfaceControl reference is passed from ViewRootImpl, can be set to // NULL to remove the reference diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index fab2f46e91c3..ccdf715e95d8 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -26,7 +26,6 @@ #include "../Properties.h" #include "../RenderNode.h" #include "CanvasContext.h" -#include "HardwareBufferRenderParams.h" #include "RenderThread.h" namespace android { @@ -93,9 +92,6 @@ void DrawFrameTask::run() { mContext->setSyncDelayDuration(systemTime(SYSTEM_TIME_MONOTONIC) - mSyncQueued); mContext->setTargetSdrHdrRatio(mRenderSdrHdrRatio); - auto hardwareBufferParams = mHardwareBufferParams; - mContext->setHardwareBufferRenderParams(hardwareBufferParams); - IRenderPipeline* pipeline = mContext->getRenderPipeline(); bool canUnblockUiThread; bool canDrawThisFrame; { @@ -155,11 +151,6 @@ void DrawFrameTask::run() { if (!canUnblockUiThread) { unblockUiThread(); } - - if (pipeline->hasHardwareBuffer()) { - auto fence = pipeline->flush(); - hardwareBufferParams.invokeRenderCallback(std::move(fence), 0); - } } bool DrawFrameTask::syncFrameState(TreeInfo& info) { @@ -185,9 +176,8 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { // This is after the prepareTree so that any pending operations // (RenderNode tree state, prefetched layers, etc...) will be flushed. - bool hasTarget = mContext->hasOutputTarget(); - if (CC_UNLIKELY(!hasTarget || !canDraw)) { - if (!hasTarget) { + if (CC_UNLIKELY(!mContext->hasSurface() || !canDraw)) { + if (!mContext->hasSurface()) { mSyncResult |= SyncResult::LostSurfaceRewardIfFound; } else { // If we have a surface but can't draw we must be stopped diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index 4130d4abe09e..4be8f6bc348a 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -27,16 +27,8 @@ #include "../Rect.h" #include "../TreeInfo.h" #include "RenderTask.h" -#include "SkColorSpace.h" -#include "SwapBehavior.h" -#include "utils/TimeUtils.h" -#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration -#include <android/hardware_buffer.h> -#endif -#include "HardwareBufferRenderParams.h" namespace android { - namespace uirenderer { class DeferredLayerUpdater; @@ -96,10 +88,6 @@ public: void forceDrawNextFrame() { mForceDrawFrame = true; } - void setHardwareBufferRenderParams(const HardwareBufferRenderParams& params) { - mHardwareBufferParams = params; - } - void setRenderSdrHdrRatio(float ratio) { mRenderSdrHdrRatio = ratio; } private: @@ -126,7 +114,6 @@ private: int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; - HardwareBufferRenderParams mHardwareBufferParams; std::function<std::function<void(bool)>(int32_t, int64_t)> mFrameCallback; std::function<void(bool)> mFrameCommitCallback; std::function<void()> mFrameCompleteCallback; diff --git a/libs/hwui/renderthread/HardwareBufferRenderParams.h b/libs/hwui/renderthread/HardwareBufferRenderParams.h deleted file mode 100644 index 91fe3f6cf273..000000000000 --- a/libs/hwui/renderthread/HardwareBufferRenderParams.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef HARDWAREBUFFERRENDERER_H_ -#define HARDWAREBUFFERRENDERER_H_ - -#include <android-base/unique_fd.h> -#include <android/hardware_buffer.h> - -#include "SkColorSpace.h" -#include "SkMatrix.h" -#include "SkSurface.h" - -namespace android { -namespace uirenderer { -namespace renderthread { - -using namespace android::uirenderer::renderthread; - -using RenderCallback = std::function<void(android::base::unique_fd&&, int)>; - -class RenderProxy; - -class HardwareBufferRenderParams { -public: - HardwareBufferRenderParams() = default; - HardwareBufferRenderParams(const SkMatrix& transform, const sk_sp<SkColorSpace>& colorSpace, - RenderCallback&& callback) - : mTransform(transform) - , mColorSpace(colorSpace) - , mRenderCallback(std::move(callback)) {} - const SkMatrix& getTransform() const { return mTransform; } - sk_sp<SkColorSpace> getColorSpace() const { return mColorSpace; } - - void invokeRenderCallback(android::base::unique_fd&& fenceFd, int status) { - if (mRenderCallback) { - std::invoke(mRenderCallback, std::move(fenceFd), status); - } - } - -private: - SkMatrix mTransform = SkMatrix::I(); - sk_sp<SkColorSpace> mColorSpace = SkColorSpace::MakeSRGB(); - RenderCallback mRenderCallback = nullptr; -}; - -} // namespace renderthread -} // namespace uirenderer -} // namespace android -#endif // HARDWAREBUFFERRENDERER_H_ diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h index c68fcdfc76f2..18cad31fda26 100644 --- a/libs/hwui/renderthread/IRenderPipeline.h +++ b/libs/hwui/renderthread/IRenderPipeline.h @@ -16,19 +16,17 @@ #pragma once -#include <SkColorSpace.h> -#include <SkRect.h> -#include <android-base/unique_fd.h> -#include <utils/RefBase.h> - -#include "ColorMode.h" #include "DamageAccumulator.h" #include "FrameInfoVisualizer.h" -#include "HardwareBufferRenderParams.h" #include "LayerUpdateQueue.h" #include "Lighting.h" #include "SwapBehavior.h" #include "hwui/Bitmap.h" +#include "ColorMode.h" + +#include <SkColorSpace.h> +#include <SkRect.h> +#include <utils/RefBase.h> class GrDirectContext; @@ -66,14 +64,10 @@ public: const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo, const std::vector<sp<RenderNode>>& renderNodes, - FrameInfoVisualizer* profiler, - const HardwareBufferRenderParams& bufferParams) = 0; + FrameInfoVisualizer* profiler) = 0; virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) = 0; virtual DeferredLayerUpdater* createTextureLayer() = 0; - [[nodiscard]] virtual android::base::unique_fd flush() = 0; - virtual void setHardwareBuffer(AHardwareBuffer* hardwareBuffer) = 0; - virtual bool hasHardwareBuffer() = 0; virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior) = 0; virtual void onStop() = 0; virtual bool isSurfaceReady() = 0; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 1e011c231343..f8e2deebc3c6 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -85,18 +85,6 @@ void RenderProxy::setName(const char* name) { mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); }); } -void RenderProxy::setHardwareBuffer(AHardwareBuffer* buffer) { - if (buffer) { - AHardwareBuffer_acquire(buffer); - } - mRenderThread.queue().post([this, hardwareBuffer = buffer]() mutable { - mContext->setHardwareBuffer(hardwareBuffer); - if (hardwareBuffer) { - AHardwareBuffer_release(hardwareBuffer); - } - }); -} - void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) { if (window) { ANativeWindow_acquire(window); } mRenderThread.queue().post([this, win = window, enableTimeout]() mutable { @@ -352,10 +340,6 @@ void RenderProxy::setContentDrawBounds(int left, int top, int right, int bottom) mDrawFrameTask.setContentDrawBounds(left, top, right, bottom); } -void RenderProxy::setHardwareBufferRenderParams(const HardwareBufferRenderParams& params) { - mDrawFrameTask.setHardwareBufferRenderParams(params); -} - void RenderProxy::setPictureCapturedCallback( const std::function<void(sk_sp<SkPicture>&&)>& callback) { mRenderThread.queue().post( diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 82072a6e2499..5dd65a0c8152 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -18,7 +18,6 @@ #define RENDERPROXY_H_ #include <SkRefCnt.h> -#include <android/hardware_buffer.h> #include <android/native_window.h> #include <android/surface_control.h> #include <cutils/compiler.h> @@ -77,7 +76,7 @@ public: void setSwapBehavior(SwapBehavior swapBehavior); bool loadSystemProperties(); void setName(const char* name); - void setHardwareBuffer(AHardwareBuffer* buffer); + void setSurface(ANativeWindow* window, bool enableTimeout = true); void setSurfaceControl(ASurfaceControl* surfaceControl); void allocateBuffers(); @@ -85,7 +84,6 @@ public: void setStopped(bool stopped); void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); void setLightGeometry(const Vector3& lightCenter, float lightRadius); - void setHardwareBufferRenderParams(const HardwareBufferRenderParams& params); void setOpaque(bool opaque); float setColorMode(ColorMode mode); void setRenderSdrHdrRatio(float ratio); diff --git a/libs/hwui/tests/unit/CanvasContextTests.cpp b/libs/hwui/tests/unit/CanvasContextTests.cpp index 9e376e32f8ea..88420a5d5c23 100644 --- a/libs/hwui/tests/unit/CanvasContextTests.cpp +++ b/libs/hwui/tests/unit/CanvasContextTests.cpp @@ -38,7 +38,7 @@ RENDERTHREAD_TEST(CanvasContext, create) { std::unique_ptr<CanvasContext> canvasContext( CanvasContext::create(renderThread, false, rootNode.get(), &contextFactory, 0, 0)); - ASSERT_FALSE(canvasContext->hasOutputTarget()); + ASSERT_FALSE(canvasContext->hasSurface()); canvasContext->destroy(); } diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index fdba9a6597c6..e1f6acc96730 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -1136,15 +1136,6 @@ </intent-filter> </activity> - <activity android:name="HardwareBufferRendererActivity" - android:label="HardwareRenderer/HardwareBufferRenderer" - android:exported="true"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="com.android.test.hwui.TEST"/> - </intent-filter> - </activity> - <activity android:name="MyLittleTextureView" android:label="HardwareRenderer/MyLittleTextureView" android:screenOrientation="fullSensor" diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareBufferRendererActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareBufferRendererActivity.java deleted file mode 100644 index e4de434f1ed2..000000000000 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareBufferRendererActivity.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.test.hwui; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorSpace; -import android.graphics.ColorSpace.Named; -import android.graphics.HardwareBufferRenderer; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.RenderNode; -import android.hardware.HardwareBuffer; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.ImageView; - -import java.time.Duration; -import java.util.concurrent.Executors; - -public class HardwareBufferRendererActivity extends Activity { - - private ImageView mImageView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mImageView = new ImageView(this); - mImageView.setBackgroundColor(Color.MAGENTA); - FrameLayout layout = new FrameLayout(this); - layout.setBackgroundColor(Color.CYAN); - layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - layout.addView(mImageView, new FrameLayout.LayoutParams(100, 100)); - setContentView(layout); - - HardwareBuffer buffer = HardwareBuffer.create(100, 100, PixelFormat.RGBA_8888, 1, - HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | HardwareBuffer.USAGE_GPU_COLOR_OUTPUT); - HardwareBufferRenderer renderer = new HardwareBufferRenderer(buffer); - RenderNode node = new RenderNode("content"); - node.setPosition(0, 0, 100, 100); - - Canvas canvas = node.beginRecording(); - canvas.drawColor(Color.BLUE); - - Paint paint = new Paint(); - paint.setColor(Color.RED); - canvas.drawRect(0f, 0f, 50f, 50f, paint); - node.endRecording(); - - renderer.setContentRoot(node); - - ColorSpace colorSpace = ColorSpace.get(Named.SRGB); - Handler handler = new Handler(Looper.getMainLooper()); - renderer.obtainRenderRequest() - .setColorSpace(colorSpace) - .draw(Executors.newSingleThreadExecutor(), result -> { - result.getFence().await(Duration.ofMillis(3000)); - handler.post(() -> { - Bitmap bitmap = Bitmap.wrapHardwareBuffer(buffer, colorSpace); - Bitmap copy = bitmap.copy(Config.ARGB_8888, false); - mImageView.setImageBitmap(copy); - }); - }); - } -} |