Merge "SurfaceFlinger: Prepare to remove BufferQueueLayer" into sc-dev
diff --git a/.clang-format b/.clang-format
index 03af56d..6725a1f 100644
--- a/.clang-format
+++ b/.clang-format
@@ -11,3 +11,4 @@
IndentWidth: 4
PenaltyBreakBeforeFirstCallParameter: 100000
SpacesBeforeTrailingComments: 1
+IncludeBlocks: Preserve
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index e2ffd02..753ce2e 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -793,6 +793,9 @@
if (module_metadata_version != 0) {
printf("Module Metadata version: %" PRId64 "\n", module_metadata_version);
}
+ printf("SDK extension versions [r=%s s=%s]\n",
+ android::base::GetProperty("build.version.extensions.r", "-").c_str(),
+ android::base::GetProperty("build.version.extensions.s", "-").c_str());
printf("Kernel: ");
DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 3a87776..83f01de 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -179,6 +179,11 @@
// want it for product APKs. Same notes as vendor above.
TryExtraMount("product", arg[2], "/postinstall/product");
+ // Try to mount the system_ext partition. update_engine doesn't do this for
+ // us, but we want it for system_ext APKs. Same notes as vendor and product
+ // above.
+ TryExtraMount("system_ext", arg[2], "/postinstall/system_ext");
+
constexpr const char* kPostInstallLinkerconfig = "/postinstall/linkerconfig";
// Try to mount /postinstall/linkerconfig. we will set it up after performing the chroot
if (mount("tmpfs", kPostInstallLinkerconfig, "tmpfs", 0, nullptr) != 0) {
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
index ee1eee2..8d1bf99 100644
--- a/include/android/imagedecoder.h
+++ b/include/android/imagedecoder.h
@@ -15,7 +15,7 @@
*/
/**
- * @defgroup ImageDecoder
+ * @defgroup ImageDecoder Android Image Decoder
*
* Functions for converting encoded images into RGBA pixels.
*
@@ -261,7 +261,8 @@
/**
* Delete the AImageDecoder.
- *
+ * @param decoder {@link AImageDecoder} object created with one of AImageDecoder_createFrom...
+ * functions.
* Available since API level 30.
*/
void AImageDecoder_delete(AImageDecoder* _Nullable decoder) __INTRODUCED_IN(30);
@@ -276,6 +277,7 @@
* Available since API level 30.
*
* @param format {@link AndroidBitmapFormat} to use for the output.
+ * @param decoder an {@link AImageDecoder} object.
* @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
* indicating the reason for the failure. On failure, the
* {@link AImageDecoder} uses the format it was already planning
@@ -307,6 +309,7 @@
*
* Available since API level 30.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param unpremultipliedRequired Pass true to leave the pixels unpremultiplied.
* @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
* indicating the reason for the failure.
@@ -335,6 +338,7 @@
*
* Available since API level 30.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param dataspace The {@link ADataSpace} to decode into. An ADataSpace
* specifies how to interpret the colors. By default,
* AImageDecoder will decode into the ADataSpace specified by
@@ -373,6 +377,7 @@
*
* Available since API level 30.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param width Width of the output (prior to cropping).
* This will affect future calls to
* {@link AImageDecoder_getMinimumStride}, which will now return
@@ -404,6 +409,7 @@
*
* Available since API level 30.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param sampleSize A subsampling rate of the original image. Must be greater
* than or equal to 1. A sampleSize of 2 means to skip every
* other pixel/line, resulting in a width and height that are
@@ -437,6 +443,7 @@
*
* Available since API level 30.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param crop Rectangle describing a crop of the decode. It must be contained inside of
* the (possibly scaled, by {@link AImageDecoder_setTargetSize})
* image dimensions. This will affect future calls to
@@ -475,6 +482,8 @@
* This is owned by the {@link AImageDecoder} and will be destroyed when the
* AImageDecoder is destroyed via {@link AImageDecoder_delete}.
*
+ * @param decoder an {@link AImageDecoder} object.
+ *
* Available since API level 30.
*/
const AImageDecoderHeaderInfo* _Nonnull AImageDecoder_getHeaderInfo(
@@ -562,7 +571,7 @@
/**
* Return the minimum stride that can be used in
- * {@link AImageDecoder_decodeImage).
+ * {@link AImageDecoder_decodeImage}.
*
* This stride provides no padding, meaning it will be exactly equal to the
* width times the number of bytes per pixel for the {@link AndroidBitmapFormat}
@@ -571,6 +580,8 @@
* If the output is scaled (via {@link AImageDecoder_setTargetSize}) and/or
* cropped (via {@link AImageDecoder_setCrop}), this takes those into account.
*
+ * @param decoder an {@link AImageDecoder} object.
+ *
* Available since API level 30.
*/
size_t AImageDecoder_getMinimumStride(AImageDecoder* _Nonnull decoder) __INTRODUCED_IN(30);
@@ -664,6 +675,8 @@
* A single frame GIF is considered to *not* be animated. This may require
* seeking past the first frame to verify whether there is a following frame.
*
+ * @param decoder an {@link AImageDecoder} object.
+ *
* Errors:
* - returns false if |decoder| is null.
*/
@@ -671,7 +684,7 @@
__INTRODUCED_IN(31);
enum {
- /*
+ /**
* Reported by {@link AImageDecoder_getRepeatCount} if the
* animation should repeat forever.
*
@@ -696,6 +709,7 @@
* an image with only one frame (i.e. {@link AImageDecoder_isAnimated} returns
* false) if the encoded image contains a repeat count.
*
+ * @param decoder an {@link AImageDecoder} object.
* @return Number of times to repeat on success or a value
* indicating the reason for the failure.
*
@@ -725,6 +739,7 @@
* skipping frames in an image with such frames may not produce the correct
* results.
*
+ * @param decoder an {@link AImageDecoder} object.
* @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
* indicating the reason for the failure.
*
@@ -755,6 +770,7 @@
* the end of the animation or an error or in the middle of the
* animation.
*
+ * @param decoder an {@link AImageDecoder} object.
* @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
* indicating the reason for the failure.
*
@@ -847,7 +863,7 @@
/**
* The rectangle of the image (within 0, 0,
- * {@link AImageDecoder_getWidth}, {@link AImageDecoder_getHeight})
+ * {@link AImageDecoderHeaderInfo_getWidth}, {@link AImageDecoderHeaderInfo_getHeight})
* updated by this frame.
*
* Introduced in API 31.
@@ -905,15 +921,15 @@
* sequential client does not need this.
*/
enum {
- // No disposal. The following frame will be drawn directly
- // on top of this one.
+ /// No disposal. The following frame will be drawn directly
+ /// on top of this one.
ANDROID_IMAGE_DECODER_DISPOSE_OP_NONE = 1,
- // The frame’s rectangle is cleared to transparent (by AImageDecoder)
- // before decoding the next frame.
+ /// The frame’s rectangle is cleared to transparent (by AImageDecoder)
+ /// before decoding the next frame.
ANDROID_IMAGE_DECODER_DISPOSE_OP_BACKGROUND = 2,
- // The frame’s rectangle is reverted to the prior frame before decoding
- // the next frame. This is handled by AImageDecoder, unless
- // {@link AImageDecoder_setInternallyHandleDisposePrevious} is set to false.
+ /// The frame’s rectangle is reverted to the prior frame before decoding
+ /// the next frame. This is handled by AImageDecoder, unless
+ /// {@link AImageDecoder_setInternallyHandleDisposePrevious} is set to false.
ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS = 3,
};
@@ -948,10 +964,10 @@
* sequential client does not need this.
*/
enum {
- // This frame replaces existing content. This corresponds
- // to webp’s “do not blend”.
+ /// This frame replaces existing content. This corresponds
+ /// to webp’s “do not blend”.
ANDROID_IMAGE_DECODER_BLEND_OP_SRC = 1,
- // This frame blends with the previous frame.
+ /// This frame blends with the previous frame.
ANDROID_IMAGE_DECODER_BLEND_OP_SRC_OVER = 2,
};
@@ -1002,6 +1018,7 @@
* When asked to decode frame i+1, AImageDecoder will now assume that
* the client provided i-1 in |pixels|.
*
+ * @param decoder an {@link AImageDecoder} object.
* @param handleInternally Whether AImageDecoder will internally
* handle ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS
* frames.
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 36fa326..9dc6983 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -228,8 +228,8 @@
*
* If a device supports the sensor additional information feature, it will
* report additional information events via {@link ASensorEvent} and will
- * have {@link ASensorEvent#type} set to
- * {@link ASENSOR_TYPE_ADDITIONAL_INFO} and {@link ASensorEvent#sensor} set
+ * have the type of {@link ASensorEvent} set to
+ * {@link ASENSOR_TYPE_ADDITIONAL_INFO} and the sensor of {@link ASensorEvent} set
* to the handle of the reporting sensor.
*
* Additional information reports consist of multiple frames ordered by
@@ -449,7 +449,7 @@
typedef struct ASensorEvent {
int32_t version; /* sizeof(struct ASensorEvent) */
int32_t sensor; /** The sensor that generates this event */
- int32_t type; /** Sensor type for the event, such as {@link ASENSOR_TYPE_ACCELEROMETER}*/
+ int32_t type; /** Sensor type for the event, such as {@link ASENSOR_TYPE_ACCELEROMETER} */
int32_t reserved0; /** do not use */
/**
* The time in nanoseconds at which the event happened, and its behavior
@@ -928,7 +928,7 @@
* Returns the sensor's handle.
*
* The handle identifies the sensor within the system and is included in the
- * {@link ASensorEvent#sensor} field of sensor events, including those sent with type
+ * sensor field of {@link ASensorEvent}, including those sent with type
* {@link ASENSOR_TYPE_ADDITIONAL_INFO}.
*
* A sensor's handle is able to be used to map {@link ASENSOR_TYPE_ADDITIONAL_INFO} events to the
diff --git a/include/android/surface_texture.h b/include/android/surface_texture.h
index 4757254..9ae211e 100644
--- a/include/android/surface_texture.h
+++ b/include/android/surface_texture.h
@@ -86,8 +86,8 @@
/**
* Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. A
* new OpenGL ES texture object is created and populated with the SurfaceTexture image frame
- * that was current at the time of the last call to {@link #detachFromGLContext}. This new
- * texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target.
+ * that was current at the time of the last call to {@link ASurfaceTexture_detachFromGLContext}.
+ * This new texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target.
*
* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
* contexts. Note, however, that the image contents are only accessible from one OpenGL ES
@@ -106,8 +106,8 @@
* Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
* This call must be made with the OpenGL ES context current on the calling thread. The OpenGL
* ES texture object will be deleted as a result of this call. After calling this method all
- * calls to {@link #updateTexImage} will fail until a successful call to {@link #attachToGLContext}
- * is made.
+ * calls to {@link ASurfaceTexture_updateTexImage} will fail until a successful call to
+ * {@link ASurfaceTexture_attachToGLContext} is made.
*
* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
* contexts. Note, however, that the image contents are only accessible from one OpenGL ES
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 6da4e9e..1800481 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -60,10 +60,6 @@
// Currently, these are only on system android (not vendor, not host)
// TODO(b/183654927) - move these into separate libraries
libbinder_device_interface_sources = [
- "AppOpsManager.cpp",
- "IAppOpsCallback.cpp",
- "IAppOpsService.cpp",
-
"IPermissionController.cpp",
"PermissionCache.cpp",
"PermissionController.cpp",
diff --git a/libs/binder/RpcConnection.cpp b/libs/binder/RpcConnection.cpp
index 1bf3d88..4aff92b 100644
--- a/libs/binder/RpcConnection.cpp
+++ b/libs/binder/RpcConnection.cpp
@@ -61,7 +61,8 @@
public:
explicit UnixSocketAddress(const char* path) : mAddr({.sun_family = AF_UNIX}) {
unsigned int pathLen = strlen(path) + 1;
- LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "%u %s", pathLen, path);
+ LOG_ALWAYS_FATAL_IF(pathLen > sizeof(mAddr.sun_path), "Socket path is too long: %u %s",
+ pathLen, path);
memcpy(mAddr.sun_path, path, pathLen);
}
virtual ~UnixSocketAddress() {}
@@ -78,11 +79,11 @@
};
bool RpcConnection::setupUnixDomainServer(const char* path) {
- return addServer(UnixSocketAddress(path));
+ return setupSocketServer(UnixSocketAddress(path));
}
bool RpcConnection::addUnixDomainClient(const char* path) {
- return addClient(UnixSocketAddress(path));
+ return addSocketClient(UnixSocketAddress(path));
}
#ifdef __BIONIC__
@@ -97,7 +98,7 @@
}) {}
virtual ~VsockSocketAddress() {}
std::string toString() const override {
- return String8::format("cid %du port %du", mAddr.svm_cid, mAddr.svm_port).c_str();
+ return String8::format("cid %u port %u", mAddr.svm_cid, mAddr.svm_port).c_str();
}
const sockaddr* addr() const override { return reinterpret_cast<const sockaddr*>(&mAddr); }
size_t addrSize() const override { return sizeof(mAddr); }
@@ -110,15 +111,27 @@
// realizing value w/ this type at compile time to avoid ubsan abort
constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
- return addServer(VsockSocketAddress(kAnyCid, port));
+ return setupSocketServer(VsockSocketAddress(kAnyCid, port));
}
bool RpcConnection::addVsockClient(unsigned int cid, unsigned int port) {
- return addClient(VsockSocketAddress(cid, port));
+ return addSocketClient(VsockSocketAddress(cid, port));
}
#endif // __BIONIC__
+bool RpcConnection::addNullDebuggingClient() {
+ unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
+
+ if (serverFd == -1) {
+ ALOGE("Could not connect to /dev/null: %s", strerror(errno));
+ return false;
+ }
+
+ addClient(std::move(serverFd));
+ return true;
+}
+
sp<IBinder> RpcConnection::getRootObject() {
ExclusiveSocket socket(sp<RpcConnection>::fromExisting(this), SocketUse::CLIENT);
return state()->getRootObject(socket.fd(), sp<RpcConnection>::fromExisting(this));
@@ -179,7 +192,7 @@
return mForServer;
}
-bool RpcConnection::addServer(const SocketAddress& addr) {
+bool RpcConnection::setupSocketServer(const SocketAddress& addr) {
LOG_ALWAYS_FATAL_IF(mServer.get() != -1, "Each RpcConnection can only have one server.");
unique_fd serverFd(
@@ -205,7 +218,7 @@
return true;
}
-bool RpcConnection::addClient(const SocketAddress& addr) {
+bool RpcConnection::addSocketClient(const SocketAddress& addr) {
unique_fd serverFd(
TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
if (serverFd == -1) {
@@ -222,14 +235,18 @@
LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
- std::lock_guard<std::mutex> _l(mSocketMutex);
- sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
- connection->fd = std::move(serverFd);
- mClients.push_back(connection);
+ addClient(std::move(serverFd));
return true;
}
-void RpcConnection::assignServerToThisThread(base::unique_fd&& fd) {
+void RpcConnection::addClient(unique_fd&& fd) {
+ std::lock_guard<std::mutex> _l(mSocketMutex);
+ sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
+ connection->fd = std::move(fd);
+ mClients.push_back(connection);
+}
+
+void RpcConnection::assignServerToThisThread(unique_fd&& fd) {
std::lock_guard<std::mutex> _l(mSocketMutex);
sp<ConnectionSocket> connection = sp<ConnectionSocket>::make();
connection->fd = std::move(fd);
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 755ff35..d934136 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -40,7 +40,7 @@
// We need to be able to send instructions over the socket for how to
// connect to a different server, and we also need to let the host
// process know that this is happening.
- ALOGE("Canot send binder from unrelated binder RPC connection.");
+ ALOGE("Cannot send binder from unrelated binder RPC connection.");
return INVALID_OPERATION;
}
@@ -498,19 +498,20 @@
}
}
- Parcel data;
- // transaction->data is owned by this function. Parcel borrows this data and
- // only holds onto it for the duration of this function call. Parcel will be
- // deleted before the 'transactionData' object.
- data.ipcSetDataReference(transaction->data,
- transactionData.size() - offsetof(RpcWireTransaction, data),
- nullptr /*object*/, 0 /*objectCount*/, do_nothing_to_transact_data);
- data.markForRpc(connection);
-
Parcel reply;
reply.markForRpc(connection);
if (replyStatus == OK) {
+ Parcel data;
+ // transaction->data is owned by this function. Parcel borrows this data and
+ // only holds onto it for the duration of this function call. Parcel will be
+ // deleted before the 'transactionData' object.
+ data.ipcSetDataReference(transaction->data,
+ transactionData.size() - offsetof(RpcWireTransaction, data),
+ nullptr /*object*/, 0 /*objectCount*/,
+ do_nothing_to_transact_data);
+ data.markForRpc(connection);
+
if (target) {
replyStatus = target->transact(transaction->code, data, &reply, transaction->flags);
} else {
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 211790d..9578372 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -101,6 +101,10 @@
// is for an RPC transaction).
void markForBinder(const sp<IBinder>& binder);
+ // Whenever possible, markForBinder should be preferred. This method is
+ // called automatically on reply Parcels for RPC transactions.
+ void markForRpc(const sp<RpcConnection>& connection);
+
// Whether this Parcel is written for RPC transactions (after calls to
// markForBinder or markForRpc).
bool isForRpc() const;
@@ -536,10 +540,6 @@
const binder_size_t* objects, size_t objectsCount,
release_func relFunc);
- // Whenever possible, markForBinder should be preferred. This method is
- // called automatically on reply Parcels for RPC transactions.
- void markForRpc(const sp<RpcConnection>& connection);
-
status_t finishWrite(size_t len);
void releaseObjects();
void acquireObjects();
diff --git a/libs/binder/include/binder/RpcConnection.h b/libs/binder/include/binder/RpcConnection.h
index efa922d..dba47b4 100644
--- a/libs/binder/include/binder/RpcConnection.h
+++ b/libs/binder/include/binder/RpcConnection.h
@@ -74,6 +74,15 @@
#endif // __BIONIC__
/**
+ * For debugging!
+ *
+ * Sets up an empty socket. All queries to this socket which require a
+ * response will never be satisfied. All data sent here will be
+ * unceremoniously cast down the bottomless pit, /dev/null.
+ */
+ [[nodiscard]] bool addNullDebuggingClient();
+
+ /**
* Query the other side of the connection for the root object hosted by that
* process's RpcServer (if one exists)
*/
@@ -109,8 +118,9 @@
friend sp<RpcConnection>;
RpcConnection();
- bool addServer(const SocketAddress& address);
- bool addClient(const SocketAddress& address);
+ bool setupSocketServer(const SocketAddress& address);
+ bool addSocketClient(const SocketAddress& address);
+ void addClient(base::unique_fd&& fd);
void assignServerToThisThread(base::unique_fd&& fd);
struct ConnectionSocket : public RefBase {
diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h
index c30ae01..aaafa36 100644
--- a/libs/binder/include/binder/Status.h
+++ b/libs/binder/include/binder/Status.h
@@ -91,6 +91,9 @@
static Status fromExceptionCode(int32_t exceptionCode,
const char* message);
+ // warning: this is still considered an error if it is constructed with a
+ // zero value error code. Please use Status::ok() instead and avoid zero
+ // error codes
static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);
static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
const String8& message);
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index b9adc9a..9e2050b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -173,7 +173,7 @@
* Available since API level 29.
*
* \param interfaceDescriptor this is a unique identifier for the class. This is used internally for
- * sanity checks on transactions.
+ * validity checks on transactions. This should be utf-8.
* \param onCreate see AIBinder_Class_onCreate.
* \param onDestroy see AIBinder_Class_onDestroy.
* \param onTransact see AIBinder_Class_onTransact.
@@ -645,7 +645,9 @@
*
* \return the class descriptor string. This pointer will never be null; a
* descriptor is required to define a class. The pointer is owned by the class
- * and will remain valid as long as the class does.
+ * and will remain valid as long as the class does. For a local class, this will
+ * be the same value (not necessarily pointer equal) as is passed into
+ * AIBinder_Class_define. Format is utf-8.
*/
const char* AIBinder_Class_getDescriptor(const AIBinder_Class* clazz) __INTRODUCED_IN(31);
@@ -669,7 +671,7 @@
*
* \return whether "lhs < rhs" is true
*/
-bool AIBinder_lt(const AIBinder* lhs, const AIBinder* rhs);
+bool AIBinder_lt(const AIBinder* lhs, const AIBinder* rhs) __INTRODUCED_IN(31);
/**
* Clone an AIBinder_Weak. Useful because even if a weak binder promotes to a
@@ -683,7 +685,7 @@
* \return clone of the input parameter. This must be deleted with
* AIBinder_Weak_delete. Null if weak input parameter is also null.
*/
-AIBinder_Weak* AIBinder_Weak_clone(const AIBinder_Weak* weak);
+AIBinder_Weak* AIBinder_Weak_clone(const AIBinder_Weak* weak) __INTRODUCED_IN(31);
/**
* Whether AIBinder_Weak is less than another.
@@ -718,7 +720,7 @@
*
* \return whether "lhs < rhs" is true
*/
-bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs);
+bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs) __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h b/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
index b92a6a9..749bf21 100644
--- a/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
+++ b/libs/binder/parcel_fuzzer/include_random_parcel/fuzzbinder/random_parcel.h
@@ -20,5 +20,12 @@
#include <fuzzer/FuzzedDataProvider.h>
namespace android {
+/**
+ * Fill parcel data, including some random binder objects and FDs
+ */
void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider);
+/**
+ * Fill parcel data, but don't fill any objects.
+ */
+void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider);
} // namespace android
diff --git a/libs/binder/parcel_fuzzer/main.cpp b/libs/binder/parcel_fuzzer/main.cpp
index 78606cc..332e2ad 100644
--- a/libs/binder/parcel_fuzzer/main.cpp
+++ b/libs/binder/parcel_fuzzer/main.cpp
@@ -23,6 +23,7 @@
#include <iostream>
#include <android-base/logging.h>
+#include <binder/RpcConnection.h>
#include <fuzzbinder/random_parcel.h>
#include <fuzzer/FuzzedDataProvider.h>
@@ -32,6 +33,8 @@
#include <sys/time.h>
using android::fillRandomParcel;
+using android::RpcConnection;
+using android::sp;
void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) {
// TODO: functionality to create random parcels for libhwbinder parcels
@@ -56,7 +59,18 @@
provider.ConsumeIntegralInRange<size_t>(0, maxInstructions));
P p;
- fillRandomParcel(&p, std::move(provider));
+ if constexpr (std::is_same_v<P, android::Parcel>) {
+ if (provider.ConsumeBool()) {
+ auto connection = sp<RpcConnection>::make();
+ CHECK(connection->addNullDebuggingClient());
+ p.markForRpc(connection);
+ fillRandomParcelData(&p, std::move(provider));
+ } else {
+ fillRandomParcel(&p, std::move(provider));
+ }
+ } else {
+ fillRandomParcel(&p, std::move(provider));
+ }
// since we are only using a byte to index
CHECK(reads.size() <= 255) << reads.size();
diff --git a/libs/binder/parcel_fuzzer/random_parcel.cpp b/libs/binder/parcel_fuzzer/random_parcel.cpp
index 9ca4c8a..b045a22 100644
--- a/libs/binder/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/parcel_fuzzer/random_parcel.cpp
@@ -75,4 +75,9 @@
}
}
+void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) {
+ std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(provider.remaining_bytes());
+ CHECK(OK == p->write(data.data(), data.size()));
+}
+
} // namespace android
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index e12a429..57c9013 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -65,15 +65,15 @@
// rustified
"--constified-enum", "android::c_interface::consts::.*",
- "--whitelist-type", "android::c_interface::.*",
- "--whitelist-type", "AStatus",
- "--whitelist-type", "AIBinder_Class",
- "--whitelist-type", "AIBinder",
- "--whitelist-type", "AIBinder_Weak",
- "--whitelist-type", "AIBinder_DeathRecipient",
- "--whitelist-type", "AParcel",
- "--whitelist-type", "binder_status_t",
- "--whitelist-function", ".*",
+ "--allowlist-type", "android::c_interface::.*",
+ "--allowlist-type", "AStatus",
+ "--allowlist-type", "AIBinder_Class",
+ "--allowlist-type", "AIBinder",
+ "--allowlist-type", "AIBinder_Weak",
+ "--allowlist-type", "AIBinder_DeathRecipient",
+ "--allowlist-type", "AParcel",
+ "--allowlist-type", "binder_status_t",
+ "--allowlist-function", ".*",
],
shared_libs: [
"libbinder_ndk",
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 0bf76c6..607860f 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -114,8 +114,8 @@
source_stem: "bindings",
cpp_std: "gnu++17",
bindgen_flags: [
- "--whitelist-type", "Transaction",
- "--whitelist-var", "TESTDATA_.*",
+ "--allowlist-type", "Transaction",
+ "--allowlist-var", "TESTDATA_.*",
],
shared_libs: [
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index afc4b1b..f303b7c 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -151,6 +151,27 @@
require_root: true,
}
+cc_benchmark {
+ name: "binderRpcBenchmark",
+ defaults: ["binder_test_defaults"],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ srcs: [
+ "binderRpcBenchmark.cpp",
+ "IBinderRpcBenchmark.aidl",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+}
+
cc_test {
name: "binderThroughputTest",
defaults: ["binder_test_defaults"],
diff --git a/libs/binder/tests/IBinderRpcBenchmark.aidl b/libs/binder/tests/IBinderRpcBenchmark.aidl
new file mode 100644
index 0000000..1457422
--- /dev/null
+++ b/libs/binder/tests/IBinderRpcBenchmark.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+interface IBinderRpcBenchmark {
+ @utf8InCpp String repeatString(@utf8InCpp String str);
+ IBinder repeatBinder(IBinder binder);
+}
diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp
new file mode 100644
index 0000000..7c82226
--- /dev/null
+++ b/libs/binder/tests/binderRpcBenchmark.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 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 <BnBinderRpcBenchmark.h>
+#include <android-base/logging.h>
+#include <benchmark/benchmark.h>
+#include <binder/Binder.h>
+#include <binder/RpcConnection.h>
+#include <binder/RpcServer.h>
+
+#include <thread>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+using android::BBinder;
+using android::IBinder;
+using android::interface_cast;
+using android::OK;
+using android::RpcConnection;
+using android::RpcServer;
+using android::sp;
+using android::binder::Status;
+
+class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
+ Status repeatString(const std::string& str, std::string* out) override {
+ *out = str;
+ return Status::ok();
+ }
+ Status repeatBinder(const sp<IBinder>& str, sp<IBinder>* out) override {
+ *out = str;
+ return Status::ok();
+ }
+};
+
+static sp<RpcConnection> gConnection = RpcConnection::make();
+
+void BM_getRootObject(benchmark::State& state) {
+ while (state.KeepRunning()) {
+ CHECK(gConnection->getRootObject() != nullptr);
+ }
+}
+BENCHMARK(BM_getRootObject);
+
+void BM_pingTransaction(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+
+ while (state.KeepRunning()) {
+ CHECK_EQ(OK, binder->pingBinder());
+ }
+}
+BENCHMARK(BM_pingTransaction);
+
+void BM_repeatString(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+ sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+ CHECK(iface != nullptr);
+
+ // Googlers might see go/another-look-at-aidl-hidl-perf
+ //
+ // When I checked in July 2019, 99.5% of AIDL transactions and 99.99% of HIDL
+ // transactions were less than one page in size (system wide during a test
+ // involving media and camera). This is why this diverges from
+ // binderThroughputTest and hwbinderThroughputTest. Future consideration - get
+ // this data on continuous integration. Here we are testing sending a
+ // transaction of twice this size. In other cases, we should focus on
+ // benchmarks of particular usecases. If individual binder transactions like
+ // the ones tested here are fast, then Android performance will be dominated
+ // by how many binder calls work together (and by factors like the scheduler,
+ // thermal throttling, core choice, etc..).
+ std::string str = std::string(getpagesize() * 2, 'a');
+ CHECK_EQ(str.size(), getpagesize() * 2);
+
+ while (state.KeepRunning()) {
+ std::string out;
+ Status ret = iface->repeatString(str, &out);
+ CHECK(ret.isOk()) << ret;
+ }
+}
+BENCHMARK(BM_repeatString);
+
+void BM_repeatBinder(benchmark::State& state) {
+ sp<IBinder> binder = gConnection->getRootObject();
+ CHECK(binder != nullptr);
+ sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+ CHECK(iface != nullptr);
+
+ while (state.KeepRunning()) {
+ // force creation of a new address
+ sp<IBinder> binder = sp<BBinder>::make();
+
+ sp<IBinder> out;
+ Status ret = iface->repeatBinder(binder, &out);
+ CHECK(ret.isOk()) << ret;
+ }
+}
+BENCHMARK(BM_repeatBinder);
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
+
+ std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
+ (void)unlink(addr.c_str());
+
+ std::thread([addr]() {
+ sp<RpcServer> server = RpcServer::make();
+ server->setRootObject(sp<MyBinderRpcBenchmark>::make());
+
+ server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+
+ sp<RpcConnection> connection = server->addClientConnection();
+ CHECK(connection->setupUnixDomainServer(addr.c_str()));
+
+ connection->join();
+ }).detach();
+
+ for (size_t tries = 0; tries < 5; tries++) {
+ usleep(10000);
+ if (gConnection->addUnixDomainClient(addr.c_str())) goto success;
+ }
+ LOG(FATAL) << "Could not connect.";
+success:
+
+ ::benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index a51c987..3340293 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -199,13 +199,8 @@
static std::string allocateSocketAddress() {
static size_t id = 0;
- static bool gUseTmp = access("/tmp/", F_OK) != -1;
-
- if (gUseTmp) {
- return "/tmp/binderRpcTest_" + std::to_string(id++);
- } else {
- return "/dev/binderRpcTest_" + std::to_string(id++);
- }
+ std::string temp = getenv("TMPDIR") ?: "/tmp";
+ return temp + "/binderRpcTest_" + std::to_string(id++);
};
struct ProcessConnection {
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index ffb3ef2..c857d62 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -226,7 +226,7 @@
IncrementNativeHandle,
IncrementNoCopyNoMove,
IncrementParcelableVector,
- ToUpper,
+ DoubleString,
CallMeBack,
IncrementInt32,
IncrementUint32,
@@ -256,7 +256,7 @@
virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
virtual status_t increment(const std::vector<TestParcelable>& a,
std::vector<TestParcelable>* aPlusOne) const = 0;
- virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
+ virtual status_t doubleString(const String8& str, String8* doubleStr) const = 0;
// As mentioned above, sp<IBinder> is already tested by setDeathToken
virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
virtual status_t increment(int32_t a, int32_t* aPlusOne) const = 0;
@@ -329,9 +329,10 @@
std::vector<TestParcelable>*);
return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
}
- status_t toUpper(const String8& str, String8* upperStr) const override {
+ status_t doubleString(const String8& str, String8* doubleStr) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
- return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
+ return callRemote<decltype(&ISafeInterfaceTest::doubleString)>(Tag::DoubleString, str,
+ doubleStr);
}
void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
@@ -454,10 +455,9 @@
}
return NO_ERROR;
}
- status_t toUpper(const String8& str, String8* upperStr) const override {
+ status_t doubleString(const String8& str, String8* doubleStr) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
- *upperStr = str;
- upperStr->toUpper();
+ *doubleStr = str + str;
return NO_ERROR;
}
void callMeBack(const sp<ICallback>& callback, int32_t a) const override {
@@ -548,8 +548,8 @@
std::vector<TestParcelable>*) const;
return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
}
- case ISafeInterfaceTest::Tag::ToUpper: {
- return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
+ case ISafeInterfaceTest::Tag::DoubleString: {
+ return callLocal(data, reply, &ISafeInterfaceTest::doubleString);
}
case ISafeInterfaceTest::Tag::CallMeBack: {
return callLocalAsync(data, reply, &ISafeInterfaceTest::callMeBack);
@@ -726,12 +726,12 @@
}
}
-TEST_F(SafeInterfaceTest, TestToUpper) {
- const String8 str{"Hello, world!"};
- String8 upperStr;
- status_t result = mSafeInterfaceTest->toUpper(str, &upperStr);
+TEST_F(SafeInterfaceTest, TestDoubleString) {
+ const String8 str{"asdf"};
+ String8 doubleStr;
+ status_t result = mSafeInterfaceTest->doubleString(str, &doubleStr);
ASSERT_EQ(NO_ERROR, result);
- ASSERT_TRUE(upperStr == String8{"HELLO, WORLD!"});
+ ASSERT_TRUE(doubleStr == String8{"asdfasdf"});
}
TEST_F(SafeInterfaceTest, TestCallMeBack) {
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index bd5edbd..e3b59b2 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -498,6 +498,7 @@
bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
+ mSize = mRequestedSize;
// Only reject buffers if scaling mode is freeze.
return false;
}
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index f7962e0..56a064b 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -309,7 +309,8 @@
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
status_t result = -errno;
- ALOGE("channel '%s' ~ Could not create socket pair. errno=%d", name.c_str(), errno);
+ ALOGE("channel '%s' ~ Could not create socket pair. errno=%s(%d)", name.c_str(),
+ strerror(errno), errno);
outServerChannel.reset();
outClientChannel.reset();
return result;
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
index 9492bda..dd38224 100644
--- a/libs/permission/Android.bp
+++ b/libs/permission/Android.bp
@@ -1,5 +1,14 @@
-// TODO(b/183654927): empty place holder to start moving permission related things out of libbinder
-// (appops, permission controller, etc..)
cc_library_shared {
name: "libpermission",
+ srcs: [
+ "AppOpsManager.cpp",
+ "IAppOpsCallback.cpp",
+ "IAppOpsService.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
}
diff --git a/libs/binder/AppOpsManager.cpp b/libs/permission/AppOpsManager.cpp
similarity index 100%
rename from libs/binder/AppOpsManager.cpp
rename to libs/permission/AppOpsManager.cpp
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/permission/IAppOpsCallback.cpp
similarity index 100%
rename from libs/binder/IAppOpsCallback.cpp
rename to libs/permission/IAppOpsCallback.cpp
diff --git a/libs/binder/IAppOpsService.cpp b/libs/permission/IAppOpsService.cpp
similarity index 100%
rename from libs/binder/IAppOpsService.cpp
rename to libs/permission/IAppOpsService.cpp
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h
similarity index 100%
rename from libs/binder/include/binder/AppOpsManager.h
rename to libs/permission/include/binder/AppOpsManager.h
diff --git a/libs/binder/include/binder/IAppOpsCallback.h b/libs/permission/include/binder/IAppOpsCallback.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsCallback.h
rename to libs/permission/include/binder/IAppOpsCallback.h
diff --git a/libs/binder/include/binder/IAppOpsService.h b/libs/permission/include/binder/IAppOpsService.h
similarity index 100%
rename from libs/binder/include/binder/IAppOpsService.h
rename to libs/permission/include/binder/IAppOpsService.h
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index f395ab4..ec39137 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -48,7 +48,6 @@
name: "librenderengine_sources",
srcs: [
"Description.cpp",
- "ExternalTexture.cpp",
"Mesh.cpp",
"RenderEngine.cpp",
"Texture.cpp",
diff --git a/libs/renderengine/ExternalTexture.cpp b/libs/renderengine/ExternalTexture.cpp
deleted file mode 100644
index eabff58..0000000
--- a/libs/renderengine/ExternalTexture.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2021 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 <renderengine/ExternalTexture.h>
-#include <renderengine/RenderEngine.h>
-#include <ui/GraphicBuffer.h>
-
-#include "log/log_main.h"
-
-namespace android::renderengine {
-
-ExternalTexture::ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine,
- uint32_t usage)
- : mBuffer(buffer), mRenderEngine(renderEngine) {
- LOG_ALWAYS_FATAL_IF(buffer == nullptr,
- "Attempted to bind a null buffer to an external texture!");
- // GLESRenderEngine has a separate texture cache for output buffers,
- if (usage == Usage::WRITEABLE &&
- (mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::GLES ||
- mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::THREADED)) {
- return;
- }
- mRenderEngine.mapExternalTextureBuffer(mBuffer, usage & Usage::WRITEABLE);
-}
-
-ExternalTexture::~ExternalTexture() {
- mRenderEngine.unmapExternalTextureBuffer(mBuffer);
-}
-
-} // namespace android::renderengine
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index d87315f..a2963a7 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -746,8 +746,7 @@
return;
}
-void GLESRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool /*isRenderable*/) {
+void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
ATRACE_CALL();
mImageManager->cacheAsync(buffer, nullptr);
}
@@ -798,8 +797,8 @@
return NO_ERROR;
}
-void GLESRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
- mImageManager->releaseAsync(buffer->getId(), nullptr);
+void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
+ mImageManager->releaseAsync(bufferId, nullptr);
}
std::shared_ptr<ImageManager::Barrier> GLESRenderEngine::unbindExternalTextureBufferForTesting(
@@ -1103,7 +1102,7 @@
status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
+ const sp<GraphicBuffer>& buffer,
const bool useFramebufferCache, base::unique_fd&& bufferFence,
base::unique_fd* drawFence) {
ATRACE_CALL();
@@ -1126,7 +1125,7 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer->getBuffer());
+ validateOutputBufferUsage(buffer);
std::unique_ptr<BindNativeBufferAsFramebuffer> fbo;
// Gathering layers that requested blur, we'll need them to decide when to render to an
@@ -1143,13 +1142,11 @@
if (blurLayersSize == 0) {
fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
- buffer->getBuffer()
- .get()
- ->getNativeBuffer(),
+ buffer.get()->getNativeBuffer(),
useFramebufferCache);
if (fbo->getStatus() != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors();
return fbo->getStatus();
}
@@ -1160,7 +1157,7 @@
mBlurFilter->setAsDrawTarget(display, blurLayers.front()->backgroundBlurRadius);
if (status != NO_ERROR) {
ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors();
return status;
}
@@ -1197,7 +1194,7 @@
auto status = mBlurFilter->prepare();
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't render first blur pass");
return status;
}
@@ -1206,7 +1203,6 @@
// Done blurring, time to bind the native FBO and render our blur onto it.
fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
buffer.get()
- ->getBuffer()
->getNativeBuffer(),
useFramebufferCache);
status = fbo->getStatus();
@@ -1219,7 +1215,7 @@
}
if (status != NO_ERROR) {
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't bind native framebuffer");
return status;
}
@@ -1227,7 +1223,7 @@
status = mBlurFilter->render(blurLayersSize > 1);
if (status != NO_ERROR) {
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
- buffer->getBuffer()->handle);
+ buffer->handle);
checkErrors("Can't render blur filter");
return status;
}
@@ -1254,7 +1250,7 @@
disableTexture = false;
isOpaque = layer->source.buffer.isOpaque;
- sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer();
+ sp<GraphicBuffer> gBuf = layer->source.buffer.buffer;
validateInputBufferUsage(gBuf);
bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf,
layer->source.buffer.fence);
@@ -1278,7 +1274,7 @@
// Do not cache protected EGLImage, protected memory is limited.
if (gBuf->getUsage() & GRALLOC_USAGE_PROTECTED) {
- unmapExternalTextureBuffer(gBuf);
+ unbindExternalTextureBuffer(gBuf->getId());
}
}
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index e7ed9c0..cd7a86b 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -60,14 +60,16 @@
void primeCache() override;
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
+ void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
+ void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);
+
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
bool useProtectedContext(bool useProtectedContext) override;
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
bool cleanupPostRender(CleanupMode mode) override;
int getContextPriority() override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
@@ -103,9 +105,6 @@
EXCLUDES(mFramebufferImageCacheMutex);
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
- void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable)
- EXCLUDES(mRenderingMutex);
- void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
private:
friend class BindNativeBufferAsFramebuffer;
diff --git a/libs/renderengine/include/renderengine/ExternalTexture.h b/libs/renderengine/include/renderengine/ExternalTexture.h
deleted file mode 100644
index 07f0833..0000000
--- a/libs/renderengine/include/renderengine/ExternalTexture.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#pragma once
-
-#include <android-base/macros.h>
-#include <ui/GraphicBuffer.h>
-
-namespace android::renderengine {
-
-class RenderEngine;
-
-/**
- * Manages GPU image resources on behalf of clients using RenderEngine.
- *
- * Clients of RenderEngine are required to wrap their GraphicBuffer objects as an ExternalTexture,
- * which is then mapped into GPU resources required by RenderEngine. When a client no longer needs
- * to use the GraphicBuffer as input into RenderEngine::drawLayers, then the client should delete
- * their ExternalTexture so that resources may be freed.
- */
-class ExternalTexture {
-public:
- // Usage specifies the rendering intent for the buffer.
- enum Usage : uint32_t {
- // When a buffer is not READABLE but is WRITEABLE, then GLESRenderEngine will use that as a
- // hint to load the buffer into a separate cache
- READABLE = 1 << 0,
-
- // The buffer needs to be mapped as a 2D texture if set, otherwise must be mapped as an
- // external texture
- WRITEABLE = 1 << 1,
- };
- // Creates an ExternalTexture for the provided buffer and RenderEngine instance, with the given
- // usage hint of type Usage.
- ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine, uint32_t usage);
-
- ~ExternalTexture();
-
- // Retrieves the buffer that is bound to this texture.
- const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
-
-private:
- sp<GraphicBuffer> mBuffer;
- RenderEngine& mRenderEngine;
- DISALLOW_COPY_AND_ASSIGN(ExternalTexture);
-};
-
-} // namespace android::renderengine
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index c54c5ba..7661233 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -16,9 +16,11 @@
#pragma once
+#include <iosfwd>
+
#include <math/mat4.h>
#include <math/vec3.h>
-#include <renderengine/ExternalTexture.h>
+#include <renderengine/Texture.h>
#include <ui/BlurRegion.h>
#include <ui/Fence.h>
#include <ui/FloatRect.h>
@@ -29,8 +31,6 @@
#include <ui/StretchEffect.h>
#include <ui/Transform.h>
-#include <iosfwd>
-
namespace android {
namespace renderengine {
@@ -39,7 +39,7 @@
// Buffer containing the image that we will render.
// If buffer == nullptr, then the rest of the fields in this struct will be
// ignored.
- std::shared_ptr<ExternalTexture> buffer = nullptr;
+ sp<GraphicBuffer> buffer = nullptr;
// Fence that will fire when the buffer is ready to be bound.
sp<Fence> fence = nullptr;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index c8a0f0a..8dd98c3 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -17,20 +17,19 @@
#ifndef SF_RENDERENGINE_H_
#define SF_RENDERENGINE_H_
+#include <stdint.h>
+#include <sys/types.h>
+#include <memory>
+
#include <android-base/unique_fd.h>
#include <math/mat4.h>
#include <renderengine/DisplaySettings.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/Framebuffer.h>
#include <renderengine/Image.h>
#include <renderengine/LayerSettings.h>
-#include <stdint.h>
-#include <sys/types.h>
#include <ui/GraphicTypes.h>
#include <ui/Transform.h>
-#include <memory>
-
/**
* Allows to set RenderEngine backend to GLES (default) or SkiaGL (NOT yet supported).
*/
@@ -52,7 +51,6 @@
namespace renderengine {
-class ExternalTexture;
class Image;
class Mesh;
class Texture;
@@ -106,6 +104,23 @@
virtual void genTextures(size_t count, uint32_t* names) = 0;
virtual void deleteTextures(size_t count, uint32_t const* names) = 0;
+ // Caches Image resources for this buffer, but does not bind the buffer to
+ // a particular texture.
+ // Note that work is deferred to an additional thread, i.e. this call
+ // is made asynchronously, but the caller can expect that cache/unbind calls
+ // are performed in a manner that's conflict serializable, i.e. unbinding
+ // a buffer should never occur before binding the buffer if the caller
+ // called {bind, cache}ExternalTextureBuffer before calling unbind.
+ virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
+ // Removes internal resources referenced by the bufferId. This method should be
+ // invoked when the caller will no longer hold a reference to a GraphicBuffer
+ // and needs to clean up its resources.
+ // Note that work is deferred to an additional thread, i.e. this call
+ // is made asynchronously, but the caller can expect that cache/unbind calls
+ // are performed in a manner that's conflict serializable, i.e. unbinding
+ // a buffer should never occur before binding the buffer if the caller
+ // called {bind, cache}ExternalTextureBuffer before calling unbind.
+ virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0;
enum class CleanupMode {
CLEAN_OUTPUT_RESOURCES,
@@ -176,9 +191,8 @@
// now, this always returns NO_ERROR.
virtual status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) = 0;
+ const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0;
virtual void cleanFramebufferCache() = 0;
// Returns the priority this context was actually created with. Note: this may not be
// the same as specified at context creation time, due to implementation limits on the
@@ -199,31 +213,6 @@
static void validateOutputBufferUsage(const sp<GraphicBuffer>&);
protected:
- // Maps GPU resources for this buffer.
- // Note that work may be deferred to an additional thread, i.e. this call
- // is made asynchronously, but the caller can expect that map/unmap calls
- // are performed in a manner that's conflict serializable, i.e. unmapping
- // a buffer should never occur before binding the buffer if the caller
- // called mapExternalTextureBuffer before calling unmap.
- // Note also that if the buffer contains protected content, then mapping those GPU resources may
- // be deferred until the buffer is really used for drawing. This is because typical SoCs that
- // support protected memory only support a limited amount, so optimisitically mapping protected
- // memory may be too burdensome. If a buffer contains protected content and the RenderEngine
- // implementation supports protected context, then GPU resources may be mapped into both the
- // protected and unprotected contexts.
- // If the buffer may ever be written to by RenderEngine, then isRenderable must be true.
- virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) = 0;
- // Unmaps GPU resources used by this buffer. This method should be
- // invoked when the caller will no longer hold a reference to a GraphicBuffer
- // and needs to clean up its resources.
- // Note that if there are multiple callers holding onto the same buffer, then the buffer's
- // resources may be internally ref-counted to guard against use-after-free errors. Note that
- // work may be deferred to an additional thread, i.e. this call is expected to be made
- // asynchronously, but the caller can expect that map/unmap calls are performed in a manner
- // that's conflict serializable, i.e. unmap a buffer should never occur before binding the
- // buffer if the caller called mapExternalTextureBuffer before calling unmap.
- virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0;
- friend class ExternalTexture;
friend class threaded::RenderEngineThreaded;
const RenderEngineType mRenderEngineType;
};
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 27dbd1e..228553d 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -39,6 +39,8 @@
MOCK_METHOD1(dump, void(std::string&));
MOCK_METHOD2(genTextures, void(size_t, uint32_t*));
MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*));
+ MOCK_METHOD1(cacheExternalTextureBuffer, void(const sp<GraphicBuffer>&));
+ MOCK_METHOD1(unbindExternalTextureBuffer, void(uint64_t));
MOCK_METHOD1(drawMesh, void(const renderengine::Mesh&));
MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
@@ -48,17 +50,12 @@
MOCK_METHOD1(cleanupPostRender, bool(CleanupMode mode));
MOCK_METHOD6(drawLayers,
status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
- const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&,
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
base::unique_fd*));
MOCK_METHOD0(cleanFramebufferCache, void());
MOCK_METHOD0(getContextPriority, int());
MOCK_METHOD0(supportsBackgroundBlur, bool());
MOCK_METHOD1(onPrimaryDisplaySizeChanged, void(ui::Size));
-
-protected:
- // mock renderengine still needs to implement these, but callers should never need to call them.
- void mapExternalTextureBuffer(const sp<GraphicBuffer>&, bool) {}
- void unmapExternalTextureBuffer(const sp<GraphicBuffer>&) {}
};
} // namespace mock
diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h
index 2d61cf8..bb75878 100644
--- a/libs/renderengine/skia/AutoBackendTexture.h
+++ b/libs/renderengine/skia/AutoBackendTexture.h
@@ -21,9 +21,9 @@
#include <SkImage.h>
#include <SkSurface.h>
#include <sys/types.h>
-#include <ui/GraphicTypes.h>
#include "android-base/macros.h"
+#include "ui/GraphicTypes.h"
namespace android {
namespace renderengine {
@@ -41,18 +41,13 @@
// of shared ownership with Skia objects, so we wrap it here instead.
class LocalRef {
public:
- LocalRef(AutoBackendTexture* texture) { setTexture(texture); }
+ LocalRef() {}
~LocalRef() {
// Destroying the texture is the same as setting it to null
setTexture(nullptr);
}
- AutoBackendTexture* getTexture() const { return mTexture; }
-
- DISALLOW_COPY_AND_ASSIGN(LocalRef);
-
- private:
// Sets the texture to locally ref-track.
void setTexture(AutoBackendTexture* texture) {
if (mTexture != nullptr) {
@@ -64,6 +59,12 @@
mTexture->ref();
}
}
+
+ AutoBackendTexture* getTexture() const { return mTexture; }
+
+ DISALLOW_COPY_AND_ASSIGN(LocalRef);
+
+ private:
AutoBackendTexture* mTexture = nullptr;
};
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 1c2b2fc..1db20c0 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -46,7 +46,7 @@
} // namespace
static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
// Somewhat arbitrary dimensions, but on screen and slightly shorter, based
// on actual use.
FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30);
@@ -73,7 +73,7 @@
auto layers = std::vector<const LayerSettings*>{&layer};
// The identity matrix will generate the fast shader
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd(),
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(),
nullptr);
// This matrix, which has different scales for x and y, will
// generate the slower (more general case) version, which has variants for translucent
@@ -86,14 +86,13 @@
// clang-format on
for (auto translucent : {false, true}) {
layer.shadow.casterIsTranslucent = translucent;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture,
- const std::shared_ptr<ExternalTexture>& srcTexture) {
+ sp<GraphicBuffer> dstBuffer, sp<GraphicBuffer> srcBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -104,7 +103,7 @@
},
.source = PixelSource{.buffer =
Buffer{
- .buffer = srcTexture,
+ .buffer = srcBuffer,
.maxMasteringLuminance = 1000.f,
.maxContentLuminance = 1000.f,
}},
@@ -127,7 +126,7 @@
layer.source.buffer.isOpaque = isOpaque;
for (auto alpha : {half(.23999f), half(1.0f)}) {
layer.alpha = alpha;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -136,7 +135,7 @@
}
static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -144,11 +143,11 @@
Geometry{
.boundaries = rect,
},
+ .alpha = 1,
.source =
PixelSource{
.solidColor = half3(0.1f, 0.2f, 0.3f),
},
- .alpha = 1,
};
auto layers = std::vector<const LayerSettings*>{&layer};
@@ -156,14 +155,14 @@
layer.geometry.positionTransform = transform;
for (float roundedCornersRadius : {0.0f, 0.05f, 50.f}) {
layer.geometry.roundedCornersRadius = roundedCornersRadius;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
}
static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display,
- const std::shared_ptr<ExternalTexture>& dstTexture) {
+ sp<GraphicBuffer> dstBuffer) {
const Rect& displayRect = display.physicalDisplay;
FloatRect rect(0, 0, displayRect.width(), displayRect.height());
LayerSettings layer{
@@ -177,7 +176,7 @@
auto layers = std::vector<const LayerSettings*>{&layer};
for (int radius : {9, 60}) {
layer.backgroundBlurRadius = radius;
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
+ renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache,
base::unique_fd(), nullptr);
}
}
@@ -215,9 +214,6 @@
sp<GraphicBuffer> dstBuffer =
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usage, "primeShaderCache_dst");
-
- const auto dstTexture = std::make_shared<ExternalTexture>(dstBuffer, *renderengine,
- ExternalTexture::Usage::WRITEABLE);
// This buffer will be the source for the call to drawImageLayers. Draw
// something to it as a placeholder for what an app draws. We should draw
// something, but the details are not important. Make use of the shadow layer drawing step
@@ -226,16 +222,11 @@
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usage, "drawImageLayer_src");
- const auto srcTexture =
- std::make_shared<ExternalTexture>(srcBuffer, *renderengine,
- ExternalTexture::Usage::READABLE |
- ExternalTexture::Usage::WRITEABLE);
-
- drawSolidLayers(renderengine, display, dstTexture);
- drawShadowLayers(renderengine, display, srcTexture);
- drawBlurLayers(renderengine, display, dstTexture);
+ drawSolidLayers(renderengine, display, dstBuffer);
+ drawShadowLayers(renderengine, display, srcBuffer);
+ drawBlurLayers(renderengine, display, dstBuffer);
// The majority of shaders are related to sampling images.
- drawImageLayers(renderengine, display, dstTexture, srcTexture);
+ drawImageLayers(renderengine, display, dstBuffer, srcBuffer);
// should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
@@ -243,12 +234,12 @@
sp<GraphicBuffer> externalBuffer =
new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1,
usageExternal, "primeShaderCache_external");
- const auto externalTexture =
- std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
- ExternalTexture::Usage::READABLE);
// TODO(b/184665179) doubles number of image shader compilations, but only somewhere
// between 6 and 8 will occur in real uses.
- drawImageLayers(renderengine, display, dstTexture, externalTexture);
+ drawImageLayers(renderengine, display, dstBuffer, externalBuffer);
+ renderengine->unbindExternalTextureBuffer(externalBuffer->getId());
+
+ renderengine->unbindExternalTextureBuffer(srcBuffer->getId());
const nsecs_t timeAfter = systemTime();
const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index e781584..df40dd9 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -329,6 +329,8 @@
}
SkiaGLRenderEngine::~SkiaGLRenderEngine() {
+ cleanFramebufferCache();
+
std::lock_guard<std::mutex> lock(mRenderingMutex);
if (mBlurFilter) {
delete mBlurFilter;
@@ -482,8 +484,7 @@
sourceTransfer != destTransfer;
}
-void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool isRenderable) {
+void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
// Only run this if RE is running on its own thread. This way the access to GL
// operations is guaranteed to be happening on the same thread.
if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
@@ -504,41 +505,25 @@
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
std::lock_guard<std::mutex> lock(mRenderingMutex);
- mGraphicBufferExternalRefs[buffer->getId()]++;
-
- if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
+ auto iter = cache.find(buffer->getId());
+ if (iter != cache.end()) {
+ ALOGV("Texture already exists in cache.");
+ } else {
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
- std::make_shared<AutoBackendTexture::LocalRef>(
- new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
- isRenderable));
+ std::make_shared<AutoBackendTexture::LocalRef>();
+ imageTextureRef->setTexture(
+ new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), false));
cache.insert({buffer->getId(), imageTextureRef});
}
// restore the original state of the protected context if necessary
useProtectedContext(protectedContextState);
}
-void SkiaGLRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mRenderingMutex);
- if (const auto& iter = mGraphicBufferExternalRefs.find(buffer->getId());
- iter != mGraphicBufferExternalRefs.end()) {
- if (iter->second == 0) {
- ALOGW("Attempted to unmap GraphicBuffer <id: %" PRId64
- "> from RenderEngine texture, but the "
- "ref count was already zero!",
- buffer->getId());
- mGraphicBufferExternalRefs.erase(buffer->getId());
- return;
- }
-
- iter->second--;
-
- if (iter->second == 0) {
- mTextureCache.erase(buffer->getId());
- mProtectedTextureCache.erase(buffer->getId());
- mGraphicBufferExternalRefs.erase(buffer->getId());
- }
- }
+ mTextureCache.erase(bufferId);
+ mProtectedTextureCache.erase(bufferId);
}
sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader,
@@ -636,8 +621,8 @@
status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool /*useFramebufferCache*/,
+ const sp<GraphicBuffer>& buffer,
+ const bool useFramebufferCache,
base::unique_fd&& bufferFence, base::unique_fd* drawFence) {
ATRACE_NAME("SkiaGL::drawLayers");
@@ -660,18 +645,32 @@
return BAD_VALUE;
}
- validateOutputBufferUsage(buffer->getBuffer());
+ validateOutputBufferUsage(buffer);
auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
+ AHardwareBuffer_Desc bufferDesc;
+ AHardwareBuffer_describe(buffer->toAHardwareBuffer(), &bufferDesc);
- std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
- if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
- surfaceTextureRef = it->second;
- } else {
- surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
- new AutoBackendTexture(grContext.get(), buffer->getBuffer()->toAHardwareBuffer(),
- true));
+ std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef = nullptr;
+ if (useFramebufferCache) {
+ auto iter = cache.find(buffer->getId());
+ if (iter != cache.end()) {
+ ALOGV("Cache hit!");
+ ATRACE_NAME("Cache hit");
+ surfaceTextureRef = iter->second;
+ }
+ }
+
+ if (surfaceTextureRef == nullptr || surfaceTextureRef->getTexture() == nullptr) {
+ ATRACE_NAME("Cache miss");
+ surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
+ surfaceTextureRef->setTexture(
+ new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), true));
+ if (useFramebufferCache) {
+ ALOGD("Adding to cache");
+ cache.insert({buffer->getId(), surfaceTextureRef});
+ }
}
const ui::Dataspace dstDataspace =
@@ -877,22 +876,18 @@
SkPaint paint;
if (layer->source.buffer.buffer) {
ATRACE_NAME("DrawImage");
- validateInputBufferUsage(layer->source.buffer.buffer->getBuffer());
+ validateInputBufferUsage(layer->source.buffer.buffer);
const auto& item = layer->source.buffer;
std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr;
-
- if (const auto& iter = cache.find(item.buffer->getBuffer()->getId());
- iter != cache.end()) {
+ auto iter = cache.find(item.buffer->getId());
+ if (iter != cache.end()) {
imageTextureRef = iter->second;
} else {
- // If we didn't find the image in the cache, then create a local ref but don't cache
- // it. If we're using skia, we're guaranteed to run on a dedicated GPU thread so if
- // we didn't find anything in the cache then we intentionally did not cache this
- // buffer's resources.
- imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
- new AutoBackendTexture(grContext.get(),
- item.buffer->getBuffer()->toAHardwareBuffer(),
- false));
+ imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>();
+ imageTextureRef->setTexture(new AutoBackendTexture(grContext.get(),
+ item.buffer->toAHardwareBuffer(),
+ false));
+ cache.insert({item.buffer->getId(), imageTextureRef});
}
sk_sp<SkImage> image =
@@ -1205,6 +1200,15 @@
return eglCreatePbufferSurface(display, placeholderConfig, attributes.data());
}
+void SkiaGLRenderEngine::cleanFramebufferCache() {
+ // TODO(b/180767535) Remove this method and use b/180767535 instead, which would allow
+ // SF to control texture lifecycle more tightly rather than through custom hooks into RE.
+ std::lock_guard<std::mutex> lock(mRenderingMutex);
+ mRuntimeEffects.clear();
+ mProtectedTextureCache.clear();
+ mTextureCache.clear();
+}
+
int SkiaGLRenderEngine::getContextPriority() {
int value;
eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value);
@@ -1277,12 +1281,6 @@
StringAppendF(&result, "Skia's Wrapped Objects:\n");
gpuReporter.logOutput(result, true);
- StringAppendF(&result, "RenderEngine tracked buffers: %zu\n",
- mGraphicBufferExternalRefs.size());
- StringAppendF(&result, "Dumping buffer ids...\n");
- for (const auto& [id, refCounts] : mGraphicBufferExternalRefs) {
- StringAppendF(&result, "- 0x%" PRIx64 " - %d refs \n", id, refCounts);
- }
StringAppendF(&result, "RenderEngine AHB/BackendTexture cache size: %zu\n",
mTextureCache.size());
StringAppendF(&result, "Dumping buffer ids...\n");
@@ -1294,7 +1292,9 @@
StringAppendF(&result, "\n");
SkiaMemoryReporter gpuProtectedReporter(gpuResourceMap, true);
- mProtectedGrContext->dumpMemoryStatistics(&gpuProtectedReporter);
+ if (mProtectedGrContext) {
+ mProtectedGrContext->dumpMemoryStatistics(&gpuProtectedReporter);
+ }
StringAppendF(&result, "Skia's GPU Protected Caches: ");
gpuProtectedReporter.logTotals(result);
gpuProtectedReporter.logOutput(result);
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index e71c560..8e77c16 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -23,7 +23,6 @@
#include <GrDirectContext.h>
#include <SkSurface.h>
#include <android-base/thread_annotations.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sys/types.h>
@@ -53,12 +52,13 @@
~SkiaGLRenderEngine() override EXCLUDES(mRenderingMutex);
void primeCache() override;
+ void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
+ void unbindExternalTextureBuffer(uint64_t bufferId) override;
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
- void cleanFramebufferCache() override {}
+ const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
+ void cleanFramebufferCache() override;
int getContextPriority() override;
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
@@ -72,8 +72,6 @@
void dump(std::string& result) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
- void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
- void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
private:
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
@@ -116,9 +114,7 @@
const PixelFormat mDefaultPixelFormat;
const bool mUseColorManagement;
- // Number of external holders of ExternalTexture references, per GraphicBuffer ID.
- std::unordered_map<uint64_t, int32_t> mGraphicBufferExternalRefs GUARDED_BY(mRenderingMutex);
- // Cache of GL textures that we'll store per GraphicBuffer ID, sliced by GPU context.
+ // Cache of GL textures that we'll store per GraphicBuffer ID
std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>> mTextureCache
GUARDED_BY(mRenderingMutex);
std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>>
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index 308c5ff..51ef088 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -42,12 +42,15 @@
virtual void primeCache() override{};
virtual void genTextures(size_t /*count*/, uint32_t* /*names*/) override{};
virtual void deleteTextures(size_t /*count*/, uint32_t const* /*names*/) override{};
+ virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/){};
+ virtual void unbindExternalTextureBuffer(uint64_t /*bufferId*/){};
+
virtual bool isProtected() const override { return false; } // mInProtectedContext; }
virtual bool supportsProtectedContent() const override { return false; };
virtual bool useProtectedContext(bool /*useProtectedContext*/) override { return false; };
virtual status_t drawLayers(const DisplaySettings& /*display*/,
const std::vector<const LayerSettings*>& /*layers*/,
- const std::shared_ptr<ExternalTexture>& /*buffer*/,
+ const sp<GraphicBuffer>& /*buffer*/,
const bool /*useFramebufferCache*/,
base::unique_fd&& /*bufferFence*/,
base::unique_fd* /*drawFence*/) override {
@@ -57,11 +60,6 @@
virtual int getContextPriority() override { return 0; }
virtual void assertShadersCompiled(int numShaders) {}
virtual int reportShadersCompiled() { return 0; }
-
-protected:
- virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/,
- bool /*isRenderable*/) override;
- virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/) override;
};
} // namespace skia
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index d63c88b..7846156 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -24,7 +24,6 @@
#include <cutils/properties.h>
#include <gtest/gtest.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <sync/sync.h>
#include <ui/PixelFormat.h>
@@ -161,42 +160,27 @@
class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
public:
- std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
- return std::make_shared<
- renderengine::
- ExternalTexture>(new GraphicBuffer(DEFAULT_DISPLAY_WIDTH,
- DEFAULT_DISPLAY_HEIGHT,
- HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_READ_OFTEN |
- GRALLOC_USAGE_SW_WRITE_OFTEN |
- GRALLOC_USAGE_HW_RENDER |
- GRALLOC_USAGE_HW_TEXTURE,
- "output"),
- *mRE,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ static sp<GraphicBuffer> allocateDefaultBuffer() {
+ return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
+ HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE,
+ "output");
}
// Allocates a 1x1 buffer to fill with a solid color
- std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
- uint32_t height) {
- return std::make_shared<
- renderengine::
- ExternalTexture>(new GraphicBuffer(width, height,
- HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_READ_OFTEN |
- GRALLOC_USAGE_SW_WRITE_OFTEN |
- GRALLOC_USAGE_HW_TEXTURE,
- "input"),
- *mRE,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) {
+ return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_TEXTURE,
+ "input");
}
RenderEngineTest() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+ mBuffer = allocateDefaultBuffer();
}
~RenderEngineTest() {
@@ -227,21 +211,20 @@
}
uint8_t* pixels;
- mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
file << "P6\n";
- file << mBuffer->getBuffer()->getWidth() << "\n";
- file << mBuffer->getBuffer()->getHeight() << "\n";
+ file << mBuffer->getWidth() << "\n";
+ file << mBuffer->getHeight() << "\n";
file << 255 << "\n";
- std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
- mBuffer->getBuffer()->getHeight() * 3);
+ std::vector<uint8_t> outBuffer(mBuffer->getWidth() * mBuffer->getHeight() * 3);
auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
- for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
- const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
- for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
+ for (int32_t j = 0; j < mBuffer->getHeight(); j++) {
+ const uint8_t* src = pixels + (mBuffer->getStride() * j) * 4;
+ for (int32_t i = 0; i < mBuffer->getWidth(); i++) {
// Only copy R, G and B components
outPtr[0] = src[0];
outPtr[1] = src[1];
@@ -252,7 +235,7 @@
}
}
file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
- mBuffer->getBuffer()->unlock();
+ mBuffer->unlock();
}
void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
@@ -279,13 +262,13 @@
void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
uint8_t* pixels;
- mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
int32_t maxFails = 10;
int32_t fails = 0;
for (int32_t j = 0; j < region.getHeight(); j++) {
- const uint8_t* src = pixels +
- (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
+ const uint8_t* src =
+ pixels + (mBuffer->getStride() * (region.top + j) + region.left) * 4;
for (int32_t i = 0; i < region.getWidth(); i++) {
const uint8_t expected[4] = {r, g, b, a};
bool equal = colorCompare(src, expected);
@@ -306,7 +289,7 @@
break;
}
}
- mBuffer->getBuffer()->unlock();
+ mBuffer->unlock();
}
void expectAlpha(const Rect& rect, uint8_t a) {
@@ -404,6 +387,7 @@
base::unique_fd fence;
status_t status =
mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), &fence);
+ mCurrentBuffer = mBuffer;
int fd = fence.release();
if (fd >= 0) {
@@ -413,7 +397,7 @@
ASSERT_EQ(NO_ERROR, status);
if (layers.size() > 0 && mGLESRE != nullptr) {
- ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
+ ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
}
}
@@ -519,11 +503,17 @@
void initializeRenderEngine();
std::unique_ptr<renderengine::RenderEngine> mRE;
- std::shared_ptr<renderengine::ExternalTexture> mBuffer;
// GLESRenderEngine for testing GLES-specific behavior.
// Owened by mRE, but this is downcasted.
renderengine::gl::GLESRenderEngine* mGLESRE = nullptr;
+ // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to
+ // be freed *after* RenderEngine is destroyed, so that the EGL image is
+ // destroyed first.
+ sp<GraphicBuffer> mCurrentBuffer;
+
+ sp<GraphicBuffer> mBuffer;
+
std::vector<uint32_t> mTexNames;
};
@@ -540,7 +530,6 @@
} else {
mRE = renderEngineFactory->createRenderEngine();
}
- mBuffer = allocateDefaultBuffer();
}
struct ColorSourceVariant {
@@ -577,18 +566,18 @@
struct BufferSourceVariant {
static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
RenderEngineTest* fixture) {
- const auto buf = fixture->allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
uint32_t texName;
fixture->mRE->genTextures(1, &texName);
fixture->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
- for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
- uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
- for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
+ for (int32_t j = 0; j < buf->getHeight(); j++) {
+ uint8_t* iter = pixels + (buf->getStride() * j) * 4;
+ for (int32_t i = 0; i < buf->getWidth(); i++) {
iter[0] = uint8_t(r * 255);
iter[1] = uint8_t(g * 255);
iter[2] = uint8_t(b * 255);
@@ -597,7 +586,7 @@
}
}
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1023,14 +1012,14 @@
layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
// Here will allocate a checker board texture, but transform texture
// coordinates so that only the upper left is applied.
- const auto buf = allocateSourceBuffer(2, 2);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
// Red top left, Green top right, Blue bottom left, Black bottom right
pixels[0] = 255;
pixels[1] = 0;
@@ -1044,7 +1033,7 @@
pixels[9] = 0;
pixels[10] = 255;
pixels[11] = 255;
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1072,19 +1061,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- const auto buf = allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1111,19 +1100,19 @@
std::vector<const renderengine::LayerSettings*> layers;
renderengine::LayerSettings layer;
- const auto buf = allocateSourceBuffer(1, 1);
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint32_t texName;
RenderEngineTest::mRE->genTextures(1, &texName);
this->mTexNames.push_back(texName);
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
- buf->getBuffer()->unlock();
+ buf->unlock();
layer.source.buffer.buffer = buf;
layer.source.buffer.textureName = texName;
@@ -1244,7 +1233,8 @@
}
TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
- initializeRenderEngine();
+ const auto& renderEngineFactory = GetParam();
+ mRE = renderEngineFactory->createRenderEngine();
renderengine::DisplaySettings settings;
settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
@@ -1305,6 +1295,7 @@
layers.push_back(&layer);
status_t status = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), nullptr);
+ mCurrentBuffer = mBuffer;
ASSERT_EQ(NO_ERROR, status);
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1332,8 +1323,9 @@
layers.push_back(&layer);
status_t status = mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd(), nullptr);
+ mCurrentBuffer = mBuffer;
ASSERT_EQ(NO_ERROR, status);
- ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
+ ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId()));
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1582,6 +1574,98 @@
clearRegion();
}
+TEST_P(RenderEngineTest, drawLayers_fillsBufferAndCachesImages) {
+ const auto& renderEngineFactory = GetParam();
+
+ if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
+ // GLES-specific test
+ return;
+ }
+
+ initializeRenderEngine();
+
+ renderengine::DisplaySettings settings;
+ settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
+ settings.physicalDisplay = fullscreenRect();
+ settings.clip = fullscreenRect();
+
+ std::vector<const renderengine::LayerSettings*> layers;
+
+ renderengine::LayerSettings layer;
+ layer.geometry.boundaries = fullscreenRect().toFloatRect();
+ BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
+
+ layers.push_back(&layer);
+ invokeDraw(settings, layers);
+ uint64_t bufferId = layer.source.buffer.buffer->getId();
+ EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
+ std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
+ mGLESRE->unbindExternalTextureBufferForTesting(bufferId);
+ std::lock_guard<std::mutex> lock(barrier->mutex);
+ ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
+ [&]() REQUIRES(barrier->mutex) {
+ return barrier->isOpen;
+ }));
+ EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId));
+ EXPECT_EQ(NO_ERROR, barrier->result);
+}
+
+TEST_P(RenderEngineTest, cacheExternalBuffer_withNullBuffer) {
+ const auto& renderEngineFactory = GetParam();
+
+ if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
+ // GLES-specific test
+ return;
+ }
+
+ initializeRenderEngine();
+
+ std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
+ mGLESRE->cacheExternalTextureBufferForTesting(nullptr);
+ std::lock_guard<std::mutex> lock(barrier->mutex);
+ ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
+ [&]() REQUIRES(barrier->mutex) {
+ return barrier->isOpen;
+ }));
+ EXPECT_TRUE(barrier->isOpen);
+ EXPECT_EQ(BAD_VALUE, barrier->result);
+}
+
+TEST_P(RenderEngineTest, cacheExternalBuffer_cachesImages) {
+ const auto& renderEngineFactory = GetParam();
+
+ if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) {
+ // GLES-specific test
+ return;
+ }
+
+ initializeRenderEngine();
+
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+ uint64_t bufferId = buf->getId();
+ std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
+ mGLESRE->cacheExternalTextureBufferForTesting(buf);
+ {
+ std::lock_guard<std::mutex> lock(barrier->mutex);
+ ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
+ [&]() REQUIRES(barrier->mutex) {
+ return barrier->isOpen;
+ }));
+ EXPECT_EQ(NO_ERROR, barrier->result);
+ }
+ EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
+ barrier = mGLESRE->unbindExternalTextureBufferForTesting(bufferId);
+ {
+ std::lock_guard<std::mutex> lock(barrier->mutex);
+ ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5),
+ [&]() REQUIRES(barrier->mutex) {
+ return barrier->isOpen;
+ }));
+ EXPECT_EQ(NO_ERROR, barrier->result);
+ }
+ EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId));
+}
+
TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
initializeRenderEngine();
@@ -1774,7 +1858,7 @@
sync_wait(fd, -1);
}
- uint64_t bufferId = layer.source.buffer.buffer->getBuffer()->getId();
+ uint64_t bufferId = layer.source.buffer.buffer->getId();
uint32_t texName = layer.source.buffer.textureName;
EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId));
EXPECT_EQ(bufferId, mGLESRE->getBufferIdForTextureNameForTesting(texName));
@@ -1882,16 +1966,16 @@
// The next layer will overwrite redLayer with a GraphicBuffer that is green
// applied with a translucent alpha.
- const auto buf = allocateSourceBuffer(1, 1);
+ auto buf = allocateSourceBuffer(1, 1);
{
uint8_t* pixels;
- buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- reinterpret_cast<void**>(&pixels));
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
pixels[0] = 0;
pixels[1] = 255;
pixels[2] = 0;
pixels[3] = 255;
- buf->getBuffer()->unlock();
+ buf->unlock();
}
const renderengine::LayerSettings greenLayer{
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index e3917cc..b093e88 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -162,18 +162,15 @@
TEST_F(RenderEngineThreadedTest, drawLayers) {
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
- std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), *mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
base::unique_fd bufferFence;
base::unique_fd drawFence;
EXPECT_CALL(*mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings&,
const std::vector<const renderengine::LayerSettings*>&,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t { return NO_ERROR; });
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t { return NO_ERROR; });
status_t result = mThreadedRE->drawLayers(settings, layers, buffer, false,
std::move(bufferFence), &drawFence);
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index c9f6296..190662b 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -90,6 +90,9 @@
return !mRunning || !mFunctionCalls.empty();
});
}
+
+ // we must release the RenderEngine on the thread that created it
+ mRenderEngine.reset();
}
void RenderEngineThreaded::waitUntilInitialized() const {
@@ -157,28 +160,27 @@
resultFuture.wait();
}
-void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
- bool isRenderable) {
+void RenderEngineThreaded::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::mapExternalTextureBuffer");
- instance.mapExternalTextureBuffer(buffer, isRenderable);
+ ATRACE_NAME("REThreaded::cacheExternalTextureBuffer");
+ instance.cacheExternalTextureBuffer(buffer);
});
}
mCondition.notify_one();
}
-void RenderEngineThreaded::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
+void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) {
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::unmapExternalTextureBuffer");
- instance.unmapExternalTextureBuffer(buffer);
+ ATRACE_NAME("REThreaded::unbindExternalTextureBuffer");
+ instance.unbindExternalTextureBuffer(bufferId);
});
}
mCondition.notify_one();
@@ -240,7 +242,7 @@
status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
+ const sp<GraphicBuffer>& buffer,
const bool useFramebufferCache,
base::unique_fd&& bufferFence,
base::unique_fd* drawFence) {
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index eb6098e..61ae9b8 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -48,6 +48,8 @@
void genTextures(size_t count, uint32_t* names) override;
void deleteTextures(size_t count, uint32_t const* names) override;
+ void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
+ void unbindExternalTextureBuffer(uint64_t bufferId) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
@@ -58,19 +60,14 @@
status_t drawLayers(const DisplaySettings& display,
const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
void cleanFramebufferCache() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override;
void onPrimaryDisplaySizeChanged(ui::Size size) override;
-protected:
- void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
- void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
-
private:
void threadMain(CreateInstanceFactory factory);
void waitUntilInitialized() const;
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 497c33c..edd453a 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -48,11 +48,10 @@
"libutils",
"liblog",
"libhardware",
+ "libpermission",
],
export_include_dirs: ["include"],
- export_shared_lib_headers: ["libbinder", "libhardware"],
+ export_shared_lib_headers: ["libbinder", "libpermission", "libhardware"],
}
-
-subdirs = ["tests"]
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 4e05847..8277f51 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3157,8 +3157,9 @@
ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
"This is unexpected because the wait queue is empty, so the pipe "
"should be empty and we shouldn't have any problems writing an "
- "event to it, status=%d",
- connection->getInputChannelName().c_str(), status);
+ "event to it, status=%s(%d)",
+ connection->getInputChannelName().c_str(), statusToString(status).c_str(),
+ status);
abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
} else {
// Pipe is full and we are waiting for the app to finish process some events
@@ -3171,8 +3172,9 @@
}
} else {
ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
- "status=%d",
- connection->getInputChannelName().c_str(), status);
+ "status=%s(%d)",
+ connection->getInputChannelName().c_str(), statusToString(status).c_str(),
+ status);
abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
}
return;
@@ -3341,8 +3343,9 @@
notify = status != DEAD_OBJECT || !connection->monitor;
if (notify) {
- ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
- connection->getInputChannelName().c_str(), status);
+ ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
+ connection->getInputChannelName().c_str(), statusToString(status).c_str(),
+ status);
}
} else {
// Monitor channels are never explicitly unregistered.
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 9aecaff..4151b45 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -54,6 +54,7 @@
"libbinder",
"libsensor",
"libsensorprivacy",
+ "libpermission",
"libprotoutil",
"libcrypto",
"libbase",
@@ -74,6 +75,7 @@
"libactivitymanager_aidl",
"libsensor",
"libsensorprivacy",
+ "libpermission",
],
}
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index d243989..12f63db 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -188,7 +188,7 @@
const bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) ||
(isSecure() && !targetSettings.isSecure);
const bool bufferCanBeUsedAsHwTexture =
- mBufferInfo.mBuffer->getBuffer()->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
+ mBufferInfo.mBuffer->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
compositionengine::LayerFE::LayerSettings& layer = *result;
if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
@@ -213,7 +213,7 @@
? mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel
: defaultMaxContentLuminance;
layer.frameNumber = mCurrentFrameNumber;
- layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()->getId() : 0;
+ layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0;
const bool useFiltering =
targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering();
@@ -314,7 +314,7 @@
: Hwc2::IComposerClient::Composition::DEVICE;
}
- compositionState->buffer = mBufferInfo.mBuffer->getBuffer();
+ compositionState->buffer = mBufferInfo.mBuffer;
compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
? 0
: mBufferInfo.mBufferSlot;
@@ -442,7 +442,7 @@
void BufferLayer::gatherBufferInfo() {
mBufferInfo.mPixelFormat =
- !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->getBuffer()->format;
+ !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
mBufferInfo.mFrameLatencyNeeded = true;
}
@@ -539,10 +539,10 @@
}
if (oldBufferInfo.mBuffer != nullptr) {
- uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
- if (bufWidth != uint32_t(oldBufferInfo.mBuffer->getBuffer()->width) ||
- bufHeight != uint32_t(oldBufferInfo.mBuffer->getBuffer()->height)) {
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
+ if (bufWidth != uint32_t(oldBufferInfo.mBuffer->width) ||
+ bufHeight != uint32_t(oldBufferInfo.mBuffer->height)) {
recomputeVisibleRegions = true;
}
}
@@ -563,8 +563,8 @@
}
bool BufferLayer::isProtected() const {
- return (mBufferInfo.mBuffer != nullptr) &&
- (mBufferInfo.mBuffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED);
+ const sp<GraphicBuffer>& buffer(mBufferInfo.mBuffer);
+ return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}
// As documented in libhardware header, formats in the range
@@ -651,8 +651,8 @@
return Rect::INVALID_RECT;
}
- uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
// Undo any transformations on the buffer and return the result.
if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
@@ -683,8 +683,8 @@
return parentBounds;
}
- uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
- uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
+ uint32_t bufWidth = mBufferInfo.mBuffer->getWidth();
+ uint32_t bufHeight = mBufferInfo.mBuffer->getHeight();
// Undo any transformations on the buffer and return the result.
if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
@@ -726,7 +726,7 @@
return mBufferInfo.mCrop;
} else if (mBufferInfo.mBuffer != nullptr) {
// otherwise we use the whole buffer
- return mBufferInfo.mBuffer->getBuffer()->getBounds();
+ return mBufferInfo.mBuffer->getBounds();
} else {
// if we don't have a buffer yet, we use an empty/invalid crop
return Rect();
@@ -771,14 +771,12 @@
}
sp<GraphicBuffer> BufferLayer::getBuffer() const {
- return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr;
+ return mBufferInfo.mBuffer;
}
void BufferLayer::getDrawingTransformMatrix(bool filteringEnabled, float outMatrix[16]) {
- GLConsumer::computeTransformMatrix(outMatrix,
- mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()
- : nullptr,
- mBufferInfo.mCrop, mBufferInfo.mTransform, filteringEnabled);
+ GLConsumer::computeTransformMatrix(outMatrix, mBufferInfo.mBuffer, mBufferInfo.mCrop,
+ mBufferInfo.mTransform, filteringEnabled);
}
void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index cd3d80e..0a5235a 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -132,7 +132,7 @@
PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
- std::shared_ptr<renderengine::ExternalTexture> mBuffer;
+ sp<GraphicBuffer> mBuffer;
int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
bool mFrameLatencyNeeded{false};
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 96b2247..69d2d11 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -40,6 +40,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
+#include <renderengine/Image.h>
#include <renderengine/RenderEngine.h>
#include <utils/Log.h>
#include <utils/String8.h>
@@ -166,7 +167,7 @@
}
auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer
- : mCurrentTextureBuffer->getBuffer();
+ : mCurrentTextureBuffer->graphicBuffer();
auto err = addReleaseFence(slot, buffer, fence);
if (err != OK) {
BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err);
@@ -205,11 +206,9 @@
// before, so we need to clean up old references.
if (item->mGraphicBuffer != nullptr) {
std::lock_guard<std::mutex> lock(mImagesMutex);
- if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->getBuffer() == nullptr ||
- mImages[item->mSlot]->getBuffer()->getId() != item->mGraphicBuffer->getId()) {
- mImages[item->mSlot] = std::make_shared<
- renderengine::ExternalTexture>(item->mGraphicBuffer, mRE,
- renderengine::ExternalTexture::Usage::READABLE);
+ if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->graphicBuffer() == nullptr ||
+ mImages[item->mSlot]->graphicBuffer()->getId() != item->mGraphicBuffer->getId()) {
+ mImages[item->mSlot] = std::make_shared<Image>(item->mGraphicBuffer, mRE);
}
}
@@ -223,8 +222,8 @@
int slot = item.mSlot;
BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture,
- (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->getBuffer() != nullptr)
- ? mCurrentTextureBuffer->getBuffer()->handle
+ (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->graphicBuffer() != nullptr)
+ ? mCurrentTextureBuffer->graphicBuffer()->handle
: 0,
slot, mSlots[slot].mGraphicBuffer->handle);
@@ -232,7 +231,7 @@
// releaseBufferLocked() if we're in shared buffer mode and both buffers are
// the same.
- std::shared_ptr<renderengine::ExternalTexture> nextTextureBuffer;
+ std::shared_ptr<Image> nextTextureBuffer;
{
std::lock_guard<std::mutex> lock(mImagesMutex);
nextTextureBuffer = mImages[slot];
@@ -242,7 +241,7 @@
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
if (pendingRelease == nullptr) {
status_t status =
- releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->getBuffer());
+ releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer());
if (status < NO_ERROR) {
BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status),
status);
@@ -251,7 +250,7 @@
}
} else {
pendingRelease->currentTexture = mCurrentTexture;
- pendingRelease->graphicBuffer = mCurrentTextureBuffer->getBuffer();
+ pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer();
pendingRelease->isPending = true;
}
}
@@ -302,14 +301,14 @@
void BufferLayerConsumer::computeCurrentTransformMatrixLocked() {
BLC_LOGV("computeCurrentTransformMatrixLocked");
- if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->getBuffer() == nullptr) {
+ if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->graphicBuffer() == nullptr) {
BLC_LOGD("computeCurrentTransformMatrixLocked: "
"mCurrentTextureBuffer is nullptr");
}
GLConsumer::computeTransformMatrix(mCurrentTransformMatrix,
mCurrentTextureBuffer == nullptr
? nullptr
- : mCurrentTextureBuffer->getBuffer(),
+ : mCurrentTextureBuffer->graphicBuffer(),
getCurrentCropLocked(), mCurrentTransform,
mFilteringEnabled);
}
@@ -361,8 +360,7 @@
return mCurrentApi;
}
-std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBuffer(
- int* outSlot, sp<Fence>* outFence) const {
+sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot, sp<Fence>* outFence) const {
Mutex::Autolock lock(mMutex);
if (outSlot != nullptr) {
@@ -373,7 +371,7 @@
*outFence = mCurrentFence;
}
- return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer;
+ return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer->graphicBuffer();
}
Rect BufferLayerConsumer::getCurrentCrop() const {
@@ -458,12 +456,10 @@
void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) {
if (item.mGraphicBuffer != nullptr && item.mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
std::lock_guard<std::mutex> lock(mImagesMutex);
- const std::shared_ptr<renderengine::ExternalTexture>& oldImage = mImages[item.mSlot];
- if (oldImage == nullptr || oldImage->getBuffer() == nullptr ||
- oldImage->getBuffer()->getId() != item.mGraphicBuffer->getId()) {
- mImages[item.mSlot] = std::make_shared<
- renderengine::ExternalTexture>(item.mGraphicBuffer, mRE,
- renderengine::ExternalTexture::Usage::READABLE);
+ const std::shared_ptr<Image>& oldImage = mImages[item.mSlot];
+ if (oldImage == nullptr || oldImage->graphicBuffer() == nullptr ||
+ oldImage->graphicBuffer()->getId() != item.mGraphicBuffer->getId()) {
+ mImages[item.mSlot] = std::make_shared<Image>(item.mGraphicBuffer, mRE);
}
}
}
@@ -503,6 +499,22 @@
ConsumerBase::dumpLocked(result, prefix);
}
+
+BufferLayerConsumer::Image::Image(const sp<GraphicBuffer>& graphicBuffer,
+ renderengine::RenderEngine& engine)
+ : mGraphicBuffer(graphicBuffer), mRE(engine) {
+ if (graphicBuffer != nullptr && (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED)) {
+ return;
+ }
+ mRE.cacheExternalTextureBuffer(mGraphicBuffer);
+}
+
+BufferLayerConsumer::Image::~Image() {
+ if (mGraphicBuffer != nullptr) {
+ ALOGV("Destroying buffer: %" PRId64, mGraphicBuffer->getId());
+ mRE.unbindExternalTextureBuffer(mGraphicBuffer->getId());
+ }
+}
}; // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index 9ed80b4..dd39214 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -21,11 +21,12 @@
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
#include <gui/HdrMetadata.h>
-#include <renderengine/ExternalTexture.h>
+
#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
#include <ui/Region.h>
+
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/threads.h>
@@ -38,6 +39,7 @@
namespace renderengine {
class RenderEngine;
+class Image;
} // namespace renderengine
/*
@@ -151,8 +153,7 @@
// When outSlot is not nullptr, the current buffer slot index is also
// returned. Simiarly, when outFence is not nullptr, the current output
// fence is returned.
- std::shared_ptr<renderengine::ExternalTexture> getCurrentBuffer(
- int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const;
+ sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const;
// getCurrentCrop returns the cropping rectangle of the current buffer.
Rect getCurrentCrop() const;
@@ -257,7 +258,7 @@
// mCurrentTextureBuffer is the buffer containing the current texture. It's
// possible that this buffer is not associated with any buffer slot, so we
// must track it separately in order to support the getCurrentBuffer method.
- std::shared_ptr<renderengine::ExternalTexture> mCurrentTextureBuffer;
+ std::shared_ptr<Image> mCurrentTextureBuffer;
// mCurrentCrop is the crop rectangle that applies to the current texture.
// It gets set each time updateTexImage is called.
@@ -336,8 +337,7 @@
int mCurrentTexture;
// Shadow buffer cache for cleaning up renderengine references.
- std::shared_ptr<renderengine::ExternalTexture>
- mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex);
+ std::shared_ptr<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex);
// Separate mutex guarding the shadow buffer cache.
// mImagesMutex can be manipulated with binder threads (e.g. onBuffersAllocated)
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index ac2edbe..fa9cecf 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -71,8 +71,14 @@
// original layer and the clone should be removed at the same time so there shouldn't be any
// issue with the clone layer trying to use the texture.
if (mBufferInfo.mBuffer != nullptr && !isClone()) {
- callReleaseBufferCallback(mDrawingState.releaseBufferListener,
- mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFence);
+ // Ensure that mBuffer is uncached from RenderEngine here, as
+ // RenderEngine may have been using the buffer as an external texture
+ // after the client uncached the buffer.
+ auto& engine(mFlinger->getRenderEngine());
+ const uint64_t bufferId = mBufferInfo.mBuffer->getId();
+ engine.unbindExternalTextureBuffer(bufferId);
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener, mBufferInfo.mBuffer,
+ mBufferInfo.mFence);
}
}
@@ -338,9 +344,8 @@
return true;
}
-bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
- const sp<Fence>& acquireFence, nsecs_t postTime,
- nsecs_t desiredPresentTime, bool isAutoTimestamp,
+bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence,
+ nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& clientCacheId, uint64_t frameNumber,
std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info,
const sp<ITransactionCompletedListener>& releaseBufferListener) {
@@ -348,14 +353,12 @@
if (mCurrentState.buffer) {
mReleasePreviousBuffer = true;
- if (!mDrawingState.buffer ||
- mCurrentState.buffer->getBuffer() != mDrawingState.buffer->getBuffer()) {
+ if (mCurrentState.buffer != mDrawingState.buffer) {
// If mCurrentState has a buffer, and we are about to update again
// before swapping to drawing state, then the first buffer will be
// dropped and we should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mCurrentState.releaseBufferListener,
- mCurrentState.buffer->getBuffer(),
+ callReleaseBufferCallback(mCurrentState.releaseBufferListener, mCurrentState.buffer,
mCurrentState.acquireFence);
decrementPendingBufferCount();
if (mCurrentState.bufferSurfaceFrameTX != nullptr) {
@@ -393,8 +396,8 @@
setFrameTimelineVsyncForBufferTransaction(info, postTime);
- if (buffer && dequeueTime && *dequeueTime != 0) {
- const uint64_t bufferId = buffer->getBuffer()->getId();
+ if (dequeueTime && *dequeueTime != 0) {
+ const uint64_t bufferId = buffer->getId();
mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime,
FrameTracer::FrameEvent::DEQUEUE);
@@ -402,8 +405,8 @@
FrameTracer::FrameEvent::QUEUE);
}
- mCurrentState.width = mCurrentState.buffer->getBuffer()->getWidth();
- mCurrentState.height = mCurrentState.buffer->getBuffer()->getHeight();
+ mCurrentState.width = mCurrentState.buffer->width;
+ mCurrentState.height = mCurrentState.buffer->height;
return true;
}
@@ -652,7 +655,7 @@
}
const int32_t layerId = getSequence();
- const uint64_t bufferId = mDrawingState.buffer->getBuffer()->getId();
+ const uint64_t bufferId = mDrawingState.buffer->getId();
const uint64_t frameNumber = mDrawingState.frameNumber;
const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
@@ -686,7 +689,7 @@
return BAD_VALUE;
}
- if (!mBufferInfo.mBuffer || s.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) {
+ if (s.buffer != mBufferInfo.mBuffer) {
decrementPendingBufferCount();
}
@@ -805,13 +808,13 @@
Rect BufferStateLayer::computeCrop(const State& s) {
if (s.crop.isEmpty() && s.buffer) {
- return s.buffer->getBuffer()->getBounds();
+ return s.buffer->getBounds();
} else if (s.buffer) {
Rect crop = s.crop;
crop.left = std::max(crop.left, 0);
crop.top = std::max(crop.top, 0);
- uint32_t bufferWidth = s.buffer->getBuffer()->getWidth();
- uint32_t bufferHeight = s.buffer->getBuffer()->getHeight();
+ uint32_t bufferWidth = s.buffer->getWidth();
+ uint32_t bufferHeight = s.buffer->getHeight();
if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
bufferWidth <= std::numeric_limits<int32_t>::max()) {
crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
@@ -819,7 +822,7 @@
}
if (!crop.isValid()) {
// Crop rect is out of bounds, return whole buffer
- return s.buffer->getBuffer()->getBounds();
+ return s.buffer->getBounds();
}
return crop;
}
@@ -841,8 +844,8 @@
return false;
}
- uint32_t bufferWidth = s.buffer->getBuffer()->width;
- uint32_t bufferHeight = s.buffer->getBuffer()->height;
+ uint32_t bufferWidth = s.buffer->width;
+ uint32_t bufferHeight = s.buffer->height;
// Undo any transformations on the buffer and return the result.
if (s.bufferTransform & ui::Transform::ROT_90) {
@@ -869,16 +872,14 @@
ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
}
-void BufferStateLayer::bufferMayChange(const sp<GraphicBuffer>& newBuffer) {
- if (mDrawingState.buffer != nullptr &&
- (!mBufferInfo.mBuffer ||
- mDrawingState.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) &&
- newBuffer != mDrawingState.buffer->getBuffer()) {
+void BufferStateLayer::bufferMayChange(sp<GraphicBuffer>& newBuffer) {
+ if (mDrawingState.buffer != nullptr && mDrawingState.buffer != mBufferInfo.mBuffer &&
+ newBuffer != mDrawingState.buffer) {
// If we are about to update mDrawingState.buffer but it has not yet latched
// then we will drop a buffer and should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mDrawingState.releaseBufferListener,
- mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence);
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener, mDrawingState.buffer,
+ mDrawingState.acquireFence);
decrementPendingBufferCount();
}
}
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 4171092..24e0ad2 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -62,9 +62,9 @@
bool setTransform(uint32_t transform) override;
bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
bool setCrop(const Rect& crop) override;
- bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
- const sp<Fence>& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime,
- bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber,
+ bool setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, nsecs_t postTime,
+ nsecs_t desiredPresentTime, bool isAutoTimestamp,
+ const client_cache_t& clientCacheId, uint64_t frameNumber,
std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info,
const sp<ITransactionCompletedListener>& transactionListener) override;
bool setAcquireFence(const sp<Fence>& fence) override;
@@ -100,7 +100,7 @@
// See mPendingBufferTransactions
void decrementPendingBufferCount();
- void bufferMayChange(const sp<GraphicBuffer>& newBuffer) override;
+ void bufferMayChange(sp<GraphicBuffer>& newBuffer) override;
std::atomic<int32_t>* getPendingBufferCounter() override { return &mPendingBufferTransactions; }
std::string getPendingBufferCounterName() override { return mBlastTransactionName; }
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index f310738..44b33ef 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -102,12 +102,7 @@
return false;
}
- LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr,
- "Attempted to build the ClientCache before a RenderEngine instance was "
- "ready!");
- processBuffers[id].buffer = std::make_shared<
- renderengine::ExternalTexture>(buffer, *mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE);
+ processBuffers[id].buffer = buffer;
return true;
}
@@ -137,7 +132,7 @@
}
}
-std::shared_ptr<renderengine::ExternalTexture> ClientCache::get(const client_cache_t& cacheId) {
+sp<GraphicBuffer> ClientCache::get(const client_cache_t& cacheId) {
std::lock_guard lock(mMutex);
ClientCacheBuffer* buf = nullptr;
@@ -218,8 +213,8 @@
auto &buffers = i.second.second;
for (auto& [id, clientCacheBuffer] : buffers) {
StringAppendF(&result, "\t ID: %d, Width/Height: %d,%d\n", (int)id,
- (int)clientCacheBuffer.buffer->getBuffer()->getWidth(),
- (int)clientCacheBuffer.buffer->getBuffer()->getHeight());
+ (int)clientCacheBuffer.buffer->getWidth(),
+ (int)clientCacheBuffer.buffer->getHeight());
}
}
}
diff --git a/services/surfaceflinger/ClientCache.h b/services/surfaceflinger/ClientCache.h
index a9b8177..0d597c8 100644
--- a/services/surfaceflinger/ClientCache.h
+++ b/services/surfaceflinger/ClientCache.h
@@ -19,7 +19,6 @@
#include <android-base/thread_annotations.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
-#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -40,11 +39,7 @@
bool add(const client_cache_t& cacheId, const sp<GraphicBuffer>& buffer);
void erase(const client_cache_t& cacheId);
- std::shared_ptr<renderengine::ExternalTexture> get(const client_cache_t& cacheId);
-
- // Always called immediately after setup. Will be set to non-null, and then should never be
- // called again.
- void setRenderEngine(renderengine::RenderEngine* renderEngine) { mRenderEngine = renderEngine; }
+ sp<GraphicBuffer> get(const client_cache_t& cacheId);
void removeProcess(const wp<IBinder>& processToken);
@@ -64,7 +59,7 @@
std::mutex mMutex;
struct ClientCacheBuffer {
- std::shared_ptr<renderengine::ExternalTexture> buffer;
+ sp<GraphicBuffer> buffer;
std::set<wp<ErasedRecipient>> recipients;
};
std::map<wp<IBinder> /*caching process*/,
@@ -78,7 +73,6 @@
};
sp<CacheDeathRecipient> mDeathRecipient;
- renderengine::RenderEngine* mRenderEngine = nullptr;
bool getBuffer(const client_cache_t& cacheId, ClientCacheBuffer** outClientCacheBuffer)
REQUIRES(mMutex);
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index daee83b..f680460 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -16,16 +16,15 @@
#pragma once
-#include <renderengine/ExternalTexture.h>
+#include <cstdint>
+#include <vector>
+
#include <ui/Fence.h>
#include <ui/GraphicTypes.h>
#include <ui/Size.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
-#include <cstdint>
-#include <vector>
-
namespace android {
class GraphicBuffer;
@@ -81,8 +80,7 @@
virtual void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) = 0;
// Allocates a buffer as scratch space for GPU composition
- virtual std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
- base::unique_fd* bufferFence) = 0;
+ virtual sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) = 0;
// Queues the drawn buffer for consumption by HWC. readyFence is the fence
// which will fire when the buffer is ready for consumption.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
index a8d372c..a1230b3 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
@@ -45,8 +45,6 @@
// The DisplaySurface for this surface
sp<DisplaySurface> displaySurface;
-
- size_t maxTextureCacheSize;
};
/**
@@ -83,11 +81,6 @@
return *this;
}
- RenderSurfaceCreationArgsBuilder& setMaxTextureCacheSize(size_t maxTextureCacheSize) {
- mArgs.maxTextureCacheSize = maxTextureCacheSize;
- return *this;
- }
-
private:
RenderSurfaceCreationArgs mArgs;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index c61ec59..48a54d6 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -18,7 +18,7 @@
#include <compositionengine/ProjectionSpace.h>
#include <compositionengine/impl/HwcBufferCache.h>
-#include <renderengine/ExternalTexture.h>
+#include <renderengine/Mesh.h>
#include <ui/FloatRect.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
@@ -89,7 +89,7 @@
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
- std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
+ sp<GraphicBuffer> buffer = nullptr;
sp<Fence> acquireFence = nullptr;
Rect displayFrame = {};
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index a8a5380..5127a6f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -16,16 +16,12 @@
#pragma once
+#include <memory>
+
#include <android-base/unique_fd.h>
#include <compositionengine/RenderSurface.h>
#include <utils/StrongPointer.h>
-#include <memory>
-#include <vector>
-
-#include "renderengine/ExternalTexture.h"
-#include "renderengine/RenderEngine.h"
-
struct ANativeWindow;
namespace android {
@@ -58,8 +54,7 @@
void setProtected(bool useProtected) override;
status_t beginFrame(bool mustRecompose) override;
void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override;
- std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
- base::unique_fd* bufferFence) override;
+ sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) override;
void queueBuffer(base::unique_fd readyFence) override;
void onPresentDisplayCompleted() override;
void flip() override;
@@ -71,7 +66,7 @@
// Testing
void setPageFlipCountForTest(std::uint32_t);
void setSizeForTest(const ui::Size&);
- std::shared_ptr<renderengine::ExternalTexture>& mutableTextureForTest();
+ sp<GraphicBuffer>& mutableGraphicBufferForTest();
base::unique_fd& mutableBufferReadyForTest();
private:
@@ -80,13 +75,10 @@
// ANativeWindow being rendered into
const sp<ANativeWindow> mNativeWindow;
-
- std::vector<std::shared_ptr<renderengine::ExternalTexture>> mTextureCache;
- // Current texture being rendered into
- std::shared_ptr<renderengine::ExternalTexture> mTexture;
+ // Current buffer being rendered into
+ sp<GraphicBuffer> mGraphicBuffer;
const sp<DisplaySurface> mDisplaySurface;
ui::Size mSize;
- const size_t mMaxTextureCacheSize;
bool mProtected{false};
std::uint32_t mPageFlipCount{0};
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index 53f4a30..c5d03a7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -66,7 +66,7 @@
const Rect& getBounds() const { return mBounds; }
const Region& getVisibleRegion() const { return mVisibleRegion; }
size_t getAge() const { return mAge; }
- const std::shared_ptr<renderengine::ExternalTexture>& getBuffer() const { return mTexture; }
+ const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); }
const sp<Fence>& getDrawFence() const { return mDrawFence; }
const ProjectionSpace& getOutputSpace() const { return mOutputSpace; }
ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
@@ -87,7 +87,7 @@
void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; }
void append(const CachedSet& other) {
- mTexture = nullptr;
+ mTexture.setBuffer(nullptr, nullptr);
mOutputDataspace = ui::Dataspace::UNKNOWN;
mDrawFence = nullptr;
@@ -115,7 +115,31 @@
Region mVisibleRegion;
size_t mAge = 0;
- std::shared_ptr<renderengine::ExternalTexture> mTexture;
+ class Texture {
+ public:
+ ~Texture() { setBuffer(nullptr, nullptr); }
+
+ void setBuffer(const sp<GraphicBuffer>& buffer, renderengine::RenderEngine* re) {
+ if (mRE && mBuffer) {
+ mRE->unbindExternalTextureBuffer(mBuffer->getId());
+ }
+
+ mBuffer = buffer;
+ mRE = re;
+
+ if (mRE && mBuffer) {
+ mRE->cacheExternalTextureBuffer(mBuffer);
+ }
+ }
+
+ const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
+
+ private:
+ sp<GraphicBuffer> mBuffer = nullptr;
+ renderengine::RenderEngine* mRE = nullptr;
+ };
+
+ Texture mTexture;
sp<Fence> mDrawFence;
ProjectionSpace mOutputSpace;
ui::Dataspace mOutputDataspace;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index 050e264..f2f6c0b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -360,14 +360,6 @@
OutputLayerState<mat4, LayerStateField::ColorTransform> mColorTransform;
- using SurfaceDamageState = OutputLayerState<Region, LayerStateField::SurfaceDamage>;
- SurfaceDamageState
- mSurfaceDamage{[](auto layer) {
- return layer->getLayerFE().getCompositionState()->surfaceDamage;
- },
- SurfaceDamageState::getRegionToStrings(),
- SurfaceDamageState::getRegionEquals()};
-
using CompositionTypeState = OutputLayerState<hardware::graphics::composer::hal::Composition,
LayerStateField::CompositionType>;
CompositionTypeState
@@ -410,7 +402,7 @@
return std::vector<std::string>{stream.str()};
}};
- static const constexpr size_t kNumNonUniqueFields = 16;
+ static const constexpr size_t kNumNonUniqueFields = 15;
std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() {
std::array<const StateInterface*, kNumNonUniqueFields> constFields =
@@ -427,8 +419,8 @@
return {
&mDisplayFrame, &mSourceCrop, &mZOrder, &mBufferTransform,
&mBlendMode, &mAlpha, &mLayerMetadata, &mVisibleRegion,
- &mOutputDataspace, &mPixelFormat, &mColorTransform, &mSurfaceDamage,
- &mCompositionType, &mSidebandStream, &mBuffer, &mSolidColor,
+ &mOutputDataspace, &mPixelFormat, &mColorTransform, &mCompositionType,
+ &mSidebandStream, &mBuffer, &mSolidColor,
};
}
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index fe858c2..a0cae6f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -39,7 +39,7 @@
MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat));
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
MOCK_METHOD2(prepareFrame, void(bool, bool));
- MOCK_METHOD1(dequeueBuffer, std::shared_ptr<renderengine::ExternalTexture>(base::unique_fd*));
+ MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*));
MOCK_METHOD1(queueBuffer, void(base::unique_fd));
MOCK_METHOD0(onPresentDisplayCompleted, void());
MOCK_METHOD0(flip, void());
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 3468b20..3ac5433 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#include <SurfaceFlingerProperties.sysprop.h>
+#include <thread>
+
#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/CompositionRefreshArgs.h>
@@ -28,9 +29,7 @@
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/impl/planner/Planner.h>
-#include <thread>
-
-#include "renderengine/ExternalTexture.h"
+#include <SurfaceFlingerProperties.sysprop.h>
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -716,11 +715,11 @@
bool skipLayer = false;
if (layer->getState().overrideInfo.buffer != nullptr) {
if (previousOverride != nullptr &&
- layer->getState().overrideInfo.buffer->getBuffer() == previousOverride) {
+ layer->getState().overrideInfo.buffer == previousOverride) {
ALOGV("Skipping redundant buffer");
skipLayer = true;
}
- previousOverride = layer->getState().overrideInfo.buffer->getBuffer();
+ previousOverride = layer->getState().overrideInfo.buffer;
}
const bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
@@ -979,15 +978,14 @@
}
base::unique_fd fd;
-
- std::shared_ptr<renderengine::ExternalTexture> tex;
+ sp<GraphicBuffer> buf;
// If we aren't doing client composition on this output, but do have a
// flipClientTarget request for this frame on this output, we still need to
// dequeue a buffer.
if (hasClientComposition || outputState.flipClientTarget) {
- tex = mRenderSurface->dequeueBuffer(&fd);
- if (tex == nullptr) {
+ buf = mRenderSurface->dequeueBuffer(&fd);
+ if (buf == nullptr) {
ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
"client composition for this frame",
mName.c_str());
@@ -1032,14 +1030,13 @@
// Check if the client composition requests were rendered into the provided graphic buffer. If
// so, we can reuse the buffer and avoid client composition.
if (mClientCompositionRequestCache) {
- if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
- clientCompositionDisplay,
+ if (mClientCompositionRequestCache->exists(buf->getId(), clientCompositionDisplay,
clientCompositionLayers)) {
outputCompositionState.reusedClientComposition = true;
setExpensiveRenderingExpected(false);
return readyFence;
}
- mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
+ mClientCompositionRequestCache->add(buf->getId(), clientCompositionDisplay,
clientCompositionLayers);
}
@@ -1072,12 +1069,12 @@
// over to RenderEngine, in which case this flag can be removed from the drawLayers interface.
const bool useFramebufferCache = outputState.layerStackInternal;
status_t status =
- renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex,
+ renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buf,
useFramebufferCache, std::move(fd), &readyFence);
if (status != NO_ERROR && mClientCompositionRequestCache) {
// If rendering was not successful, remove the request from the cache.
- mClientCompositionRequestCache->remove(tex->getBuffer()->getId());
+ mClientCompositionRequestCache->remove(buf->getId());
}
auto& timeStats = getCompositionEngine().getTimeStats();
@@ -1154,9 +1151,9 @@
std::vector<LayerFE::LayerSettings> results;
if (layer->getState().overrideInfo.buffer != nullptr) {
- if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) {
+ if (layer->getState().overrideInfo.buffer != previousOverrideBuffer) {
results = layer->getOverrideCompositionList();
- previousOverrideBuffer = layer->getState().overrideInfo.buffer->getBuffer();
+ previousOverrideBuffer = layer->getState().overrideInfo.buffer;
ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName());
} else {
ALOGV("Skipping redundant override buffer for [%s] in RE",
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 9ca8914..f640f85 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -537,7 +537,7 @@
sp<GraphicBuffer> buffer = outputIndependentState.buffer;
sp<Fence> acquireFence = outputIndependentState.acquireFence;
if (getState().overrideInfo.buffer != nullptr) {
- buffer = getState().overrideInfo.buffer->getBuffer();
+ buffer = getState().overrideInfo.buffer;
acquireFence = getState().overrideInfo.acquireFence;
}
@@ -699,7 +699,7 @@
settings.geometry = renderengine::Geometry{
.boundaries = boundaries.toFloatRect(),
};
- settings.bufferId = getState().overrideInfo.buffer->getBuffer()->getId();
+ settings.bufferId = getState().overrideInfo.buffer->getId();
settings.source = renderengine::PixelSource{
.buffer = renderengine::Buffer{
.buffer = getState().overrideInfo.buffer,
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index ef50870..3bef77d 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -25,8 +25,8 @@
#include <compositionengine/impl/DumpHelpers.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/RenderSurface.h>
+
#include <log/log.h>
-#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <ui/GraphicBuffer.h>
@@ -63,8 +63,7 @@
mDisplay(display),
mNativeWindow(args.nativeWindow),
mDisplaySurface(args.displaySurface),
- mSize(args.displayWidth, args.displayHeight),
- mMaxTextureCacheSize(args.maxTextureCacheSize) {
+ mSize(args.displayWidth, args.displayHeight) {
LOG_ALWAYS_FATAL_IF(!mNativeWindow);
}
@@ -147,8 +146,7 @@
}
}
-std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer(
- base::unique_fd* bufferFence) {
+sp<GraphicBuffer> RenderSurface::dequeueBuffer(base::unique_fd* bufferFence) {
ATRACE_CALL();
int fd = -1;
ANativeWindowBuffer* buffer = nullptr;
@@ -160,41 +158,16 @@
mDisplay.getName().c_str(), result);
// Return fast here as we can't do much more - any rendering we do
// now will just be wrong.
- return mTexture;
+ return mGraphicBuffer;
}
- ALOGW_IF(mTexture != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
- mTexture->getBuffer()->getNativeBuffer()->handle);
-
- sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer);
-
- std::shared_ptr<renderengine::ExternalTexture> texture;
-
- for (auto it = mTextureCache.begin(); it != mTextureCache.end(); it++) {
- const auto& cachedTexture = *it;
- if (cachedTexture->getBuffer()->getId() == newBuffer->getId()) {
- texture = cachedTexture;
- mTextureCache.erase(it);
- break;
- }
- }
-
- if (texture) {
- mTexture = texture;
- } else {
- mTexture = std::make_shared<
- renderengine::ExternalTexture>(GraphicBuffer::from(buffer),
- mCompositionEngine.getRenderEngine(),
- renderengine::ExternalTexture::Usage::WRITEABLE);
- }
- mTextureCache.push_back(mTexture);
- if (mTextureCache.size() > mMaxTextureCacheSize) {
- mTextureCache.erase(mTextureCache.begin());
- }
+ ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
+ mGraphicBuffer->getNativeBuffer()->handle);
+ mGraphicBuffer = GraphicBuffer::from(buffer);
*bufferFence = base::unique_fd(fd);
- return mTexture;
+ return mGraphicBuffer;
}
void RenderSurface::queueBuffer(base::unique_fd readyFence) {
@@ -204,24 +177,24 @@
// hasFlipClientTargetRequest could return true even if we haven't
// dequeued a buffer before. Try dequeueing one if we don't have a
// buffer ready.
- if (mTexture == nullptr) {
+ if (mGraphicBuffer == nullptr) {
ALOGI("Attempting to queue a client composited buffer without one "
"previously dequeued for display [%s]. Attempting to dequeue "
"a scratch buffer now",
mDisplay.getName().c_str());
- // We shouldn't deadlock here, since mTexture == nullptr only
+ // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
// after a successful call to queueBuffer, or if dequeueBuffer has
// never been called.
base::unique_fd unused;
dequeueBuffer(&unused);
}
- if (mTexture == nullptr) {
+ if (mGraphicBuffer == nullptr) {
ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
} else {
- status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(),
- mTexture->getBuffer()->getNativeBuffer(),
- dup(readyFence));
+ status_t result =
+ mNativeWindow->queueBuffer(mNativeWindow.get(),
+ mGraphicBuffer->getNativeBuffer(), dup(readyFence));
if (result != NO_ERROR) {
ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
result);
@@ -231,12 +204,11 @@
LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
} else {
mNativeWindow->cancelBuffer(mNativeWindow.get(),
- mTexture->getBuffer()->getNativeBuffer(),
- dup(readyFence));
+ mGraphicBuffer->getNativeBuffer(), dup(readyFence));
}
}
- mTexture = nullptr;
+ mGraphicBuffer = nullptr;
}
}
@@ -284,8 +256,8 @@
mSize = size;
}
-std::shared_ptr<renderengine::ExternalTexture>& RenderSurface::mutableTextureForTest() {
- return mTexture;
+sp<GraphicBuffer>& RenderSurface::mutableGraphicBufferForTest() {
+ return mGraphicBuffer;
}
} // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index 53557bb..dcb7555 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -130,7 +130,7 @@
}
bool CachedSet::hasReadyBuffer() const {
- return mTexture != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
+ return mTexture.getBuffer() != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
}
std::vector<CachedSet> CachedSet::decompose() const {
@@ -217,27 +217,21 @@
sp<GraphicBuffer> buffer = new GraphicBuffer(static_cast<uint32_t>(mBounds.getWidth()),
static_cast<uint32_t>(mBounds.getHeight()),
HAL_PIXEL_FORMAT_RGBA_8888, 1, usageFlags);
- const auto texture = std::make_shared<
- renderengine::ExternalTexture>(buffer, renderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
LOG_ALWAYS_FATAL_IF(buffer->initCheck() != OK);
base::unique_fd drawFence;
- status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, mTexture,
- false, base::unique_fd(), &drawFence);
+ status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, buffer, false,
+ base::unique_fd(), &drawFence);
if (result == NO_ERROR) {
+ mTexture.setBuffer(buffer, &renderEngine);
mDrawFence = new Fence(drawFence.release());
mOutputSpace = ProjectionSpace(ui::Size(outputState.framebufferSpace.bounds.getWidth(),
outputState.framebufferSpace.bounds.getHeight()),
mBounds);
- mTexture = std::move(texture);
mOutputSpace.orientation = outputState.framebufferSpace.orientation;
mOutputDataspace = outputDataspace;
mOrientation = orientation;
- } else {
- mTexture = nullptr;
}
}
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
index 7c32e94..ab85997 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp
@@ -161,7 +161,6 @@
lhs.mVisibleRegion == rhs.mVisibleRegion &&
lhs.mOutputDataspace == rhs.mOutputDataspace && lhs.mPixelFormat == rhs.mPixelFormat &&
lhs.mColorTransform == rhs.mColorTransform &&
- lhs.mSurfaceDamage == rhs.mSurfaceDamage &&
lhs.mCompositionType == rhs.mCompositionType &&
lhs.mSidebandStream == rhs.mSidebandStream && lhs.mBuffer == rhs.mBuffer &&
(lhs.mCompositionType.get() != hal::Composition::SOLID_COLOR ||
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 3a2534b..ad75557 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -111,12 +111,7 @@
const GraphicBuffer* currentOverrideBuffer = nullptr;
bool hasSkippedLayers = false;
for (auto layer : layers) {
- if (!layer->getState().overrideInfo.buffer) {
- continue;
- }
-
- const GraphicBuffer* overrideBuffer =
- layer->getState().overrideInfo.buffer->getBuffer().get();
+ const GraphicBuffer* overrideBuffer = layer->getState().overrideInfo.buffer.get();
if (overrideBuffer != nullptr && overrideBuffer == currentOverrideBuffer) {
// Skip this layer since it is part of a previous cached set
hasSkippedLayers = true;
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 4c3f494..8a4d161 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -26,7 +26,6 @@
#include "MockHWC2.h"
#include "MockHWComposer.h"
#include "RegionMatcher.h"
-#include "renderengine/mock/RenderEngine.h"
namespace android::compositionengine {
namespace {
@@ -716,7 +715,7 @@
static const HdrMetadata kHdrMetadata;
static native_handle_t* kSidebandStreamHandle;
static const sp<GraphicBuffer> kBuffer;
- std::shared_ptr<renderengine::ExternalTexture> kOverrideBuffer;
+ static const sp<GraphicBuffer> kOverrideBuffer;
static const sp<Fence> kFence;
static const sp<Fence> kOverrideFence;
static const std::string kLayerGenericMetadata1Key;
@@ -725,11 +724,6 @@
static const std::vector<uint8_t> kLayerGenericMetadata2Value;
OutputLayerWriteStateToHWCTest() {
- kOverrideBuffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::
- WRITEABLE);
auto& outputLayerState = mOutputLayer.editState();
outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
@@ -845,7 +839,6 @@
std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
- renderengine::mock::RenderEngine mRenderEngine;
};
const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
@@ -865,6 +858,7 @@
native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
reinterpret_cast<native_handle_t*>(1031);
const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
+const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kOverrideBuffer = new GraphicBuffer();
const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
const sp<Fence> OutputLayerWriteStateToHWCTest::kOverrideFence = new Fence();
const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
@@ -1029,7 +1023,7 @@
kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
kOverrideSurfaceDamage);
- expectSetHdrMetadataAndBufferCalls(kOverrideBuffer->getBuffer(), kOverrideFence);
+ expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index e80100c..5f0b0ee 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <cmath>
+
#include <android-base/stringprintf.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Output.h>
@@ -29,12 +31,9 @@
#include <ui/Rect.h>
#include <ui/Region.h>
-#include <cmath>
-
#include "CallOrderStateMachineHelper.h"
#include "MockHWC2.h"
#include "RegionMatcher.h"
-#include "renderengine/ExternalTexture.h"
namespace android::compositionengine {
namespace {
@@ -2961,10 +2960,7 @@
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
StrictMock<OutputPartialMock> mOutput;
- std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
std::optional<base::unique_fd> mReadyFence;
};
@@ -3177,10 +3173,7 @@
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
- const auto otherOutputBuffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
+ sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
.WillOnce(Return(mOutputBuffer))
.WillOnce(Return(otherOutputBuffer));
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 9aeb290..5ef5d7b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -15,8 +15,6 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "renderengine/ExternalTexture.h"
-#include "ui/GraphicBuffer.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wextra"
@@ -241,9 +239,9 @@
DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
base::unique_fd fence;
- EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence)->getBuffer().get());
+ EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence).get());
- EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest()->getBuffer().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
}
/*
@@ -251,11 +249,8 @@
*/
TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) {
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
- renderengine::ExternalTexture::Usage::READABLE |
- renderengine::ExternalTexture::Usage::WRITEABLE);
- mSurface.mutableTextureForTest() = buffer;
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ mSurface.mutableGraphicBufferForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
@@ -266,45 +261,43 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) {
- const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
- mRenderEngine, false);
- mSurface.mutableTextureForTest() = buffer;
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ mSurface.mutableGraphicBufferForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
state.flipClientTarget = false;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) {
- const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
- mRenderEngine, false);
- mSurface.mutableTextureForTest() = buffer;
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ mSurface.mutableGraphicBufferForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
state.flipClientTarget = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) {
@@ -324,28 +317,27 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) {
- const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
- mRenderEngine, false);
- mSurface.mutableTextureForTest() = buffer;
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ mSurface.mutableGraphicBufferForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
.WillOnce(Return(INVALID_OPERATION));
EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true));
- EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
}
/*
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index 283c692..f01fe27 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -305,8 +305,8 @@
const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layers,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> size_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> size_t {
EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.physicalDisplay);
EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip);
EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation),
@@ -321,6 +321,7 @@
EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
+ EXPECT_CALL(mRenderEngine, cacheExternalTextureBuffer(_));
cachedSet.render(mRenderEngine, mOutputState);
expectReadyBuffer(cachedSet);
@@ -330,6 +331,7 @@
cachedSet.getOutputSpace().bounds);
// Now check that appending a new cached set properly cleans up RenderEngine resources.
+ EXPECT_CALL(mRenderEngine, unbindExternalTextureBuffer(_));
CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
cachedSet.append(CachedSet(layer3));
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
index 47b1ae8..83cc19b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
@@ -793,47 +793,6 @@
EXPECT_TRUE(otherLayerState->compare(*mLayerState));
}
-TEST_F(LayerStateTest, updateSurfaceDamage) {
- OutputLayerCompositionState outputLayerCompositionState;
- LayerFECompositionState layerFECompositionState;
- layerFECompositionState.surfaceDamage = sRegionOne;
- setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
- layerFECompositionState);
- mLayerState = std::make_unique<LayerState>(&mOutputLayer);
-
- mock::OutputLayer newOutputLayer;
- mock::LayerFE newLayerFE;
- OutputLayerCompositionState outputLayerCompositionStateTwo;
- LayerFECompositionState layerFECompositionStateTwo;
- layerFECompositionStateTwo.surfaceDamage = sRegionTwo;
- setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
- layerFECompositionStateTwo);
- Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
- EXPECT_EQ(Flags<LayerStateField>(LayerStateField::SurfaceDamage), updates);
-}
-
-TEST_F(LayerStateTest, compareSurfaceDamage) {
- OutputLayerCompositionState outputLayerCompositionState;
- LayerFECompositionState layerFECompositionState;
- layerFECompositionState.surfaceDamage = sRegionOne;
- setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState,
- layerFECompositionState);
- mLayerState = std::make_unique<LayerState>(&mOutputLayer);
- mock::OutputLayer newOutputLayer;
- mock::LayerFE newLayerFE;
- OutputLayerCompositionState outputLayerCompositionStateTwo;
- LayerFECompositionState layerFECompositionStateTwo;
- layerFECompositionStateTwo.surfaceDamage = sRegionTwo;
- setupMocksForLayer(newOutputLayer, newLayerFE, outputLayerCompositionStateTwo,
- layerFECompositionStateTwo);
- auto otherLayerState = std::make_unique<LayerState>(&newOutputLayer);
-
- verifyNonUniqueDifferingFields(*mLayerState, *otherLayerState, LayerStateField::SurfaceDamage);
-
- EXPECT_TRUE(mLayerState->compare(*otherLayerState));
- EXPECT_TRUE(otherLayerState->compare(*mLayerState));
-}
-
TEST_F(LayerStateTest, updateSidebandStream) {
OutputLayerCompositionState outputLayerCompositionState;
LayerFECompositionState layerFECompositionState;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 8692ee6..b7b2cc6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -70,13 +70,11 @@
mIsPrimary(args.isPrimary) {
mCompositionDisplay->editState().isSecure = args.isSecure;
mCompositionDisplay->createRenderSurface(
- compositionengine::
- RenderSurfaceCreationArgs{ANativeWindow_getWidth(args.nativeWindow.get()),
- ANativeWindow_getHeight(args.nativeWindow.get()),
- args.nativeWindow, args.displaySurface,
- static_cast<size_t>(
- SurfaceFlinger::
- maxFrameBufferAcquiredBuffers)});
+ compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth(
+ args.nativeWindow.get()),
+ ANativeWindow_getHeight(
+ args.nativeWindow.get()),
+ args.nativeWindow, args.displaySurface});
if (!mFlinger->mDisableClientCompositionCache &&
SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cf215ad..b45f2bc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -880,7 +880,7 @@
}
// Allow BufferStateLayer to release any unlatched buffers in drawing state.
- bufferMayChange(c.buffer->getBuffer());
+ bufferMayChange(c.buffer);
// Commit the transaction
commitTransaction(c);
@@ -891,11 +891,7 @@
void Layer::commitTransaction(State& stateToCommit) {
if (auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
- ((mDrawingState.buffer && stateToCommit.buffer &&
- mDrawingState.buffer->getBuffer() != stateToCommit.buffer->getBuffer()) ||
- (mDrawingState.buffer && !stateToCommit.buffer) ||
- (!mDrawingState.buffer && stateToCommit.buffer)) &&
- bufferSurfaceFrame != nullptr &&
+ mDrawingState.buffer != stateToCommit.buffer && bufferSurfaceFrame != nullptr &&
bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
// If the previous buffer was committed but not latched (refreshPending - happens during
// back to back invalidates), it gets silently dropped here. Mark the corresponding
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9f3ea9a..5379d74 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -203,7 +203,7 @@
Region transparentRegionHint;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
+ sp<GraphicBuffer> buffer;
client_cache_t clientCacheId;
sp<Fence> acquireFence;
std::shared_ptr<FenceTime> acquireFenceTime;
@@ -404,11 +404,10 @@
// Used only to set BufferStateLayer state
virtual bool setTransform(uint32_t /*transform*/) { return false; };
virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
- virtual bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& /*buffer*/,
- const sp<Fence>& /*acquireFence*/, nsecs_t /*postTime*/,
- nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
- const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */,
- std::optional<nsecs_t> /* dequeueTime */,
+ virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/, const sp<Fence>& /*acquireFence*/,
+ nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/,
+ bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/,
+ uint64_t /* frameNumber */, std::optional<nsecs_t> /* dequeueTime */,
const FrameTimelineInfo& /*info*/,
const sp<ITransactionCompletedListener>& /* releaseBufferListener */) {
return false;
@@ -710,7 +709,7 @@
* Called before updating the drawing state buffer. Used by BufferStateLayer to release any
* unlatched buffers in the drawing state.
*/
- virtual void bufferMayChange(const sp<GraphicBuffer>& /* newBuffer */){};
+ virtual void bufferMayChange(sp<GraphicBuffer>& /* newBuffer */){};
/*
* Remove relative z for the layer if its relative parent is not part of the
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index a9fd16c..7a3e433 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -208,8 +208,7 @@
return true;
}
-const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
-RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
+const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
if (mBufferCache.find(fps) == mBufferCache.end()) {
// Ensure the range is > 0, so we don't divide by 0.
const auto rangeLength = std::max(1u, mHighFps - mLowFps);
@@ -223,17 +222,7 @@
color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
color.a = ALPHA;
- auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner);
- std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
- std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
- [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
- return std::make_shared<
- renderengine::ExternalTexture>(buffer,
- mFlinger.getRenderEngine(),
- renderengine::ExternalTexture::
- Usage::READABLE);
- });
- mBufferCache.emplace(fps, textures);
+ mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner));
}
return mBufferCache[fps];
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index aa8329c..c16cfa0 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -16,14 +16,13 @@
#pragma once
+#include <unordered_map>
+
#include <math/vec4.h>
-#include <renderengine/RenderEngine.h>
#include <ui/Rect.h>
#include <ui/Size.h>
#include <utils/StrongPointer.h>
-#include <unordered_map>
-
#include "Fps.h"
namespace android {
@@ -71,8 +70,7 @@
};
bool createLayer();
- const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& getOrCreateBuffers(
- uint32_t fps);
+ const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps);
SurfaceFlinger& mFlinger;
const sp<Client> mClient;
@@ -80,8 +78,7 @@
sp<IBinder> mIBinder;
sp<IGraphicBufferProducer> mGbp;
- std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>
- mBufferCache;
+ std::unordered_map<int, std::vector<sp<GraphicBuffer>>> mBufferCache;
std::optional<int> mCurrentFps;
int mFrame = 0;
static constexpr float ALPHA = 0.8f;
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 00090d9..d0032ac 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -438,22 +438,18 @@
mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
};
- std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
- if (mCachedBuffer && mCachedBuffer->getBuffer()->getWidth() == sampledBounds.getWidth() &&
- mCachedBuffer->getBuffer()->getHeight() == sampledBounds.getHeight()) {
+ sp<GraphicBuffer> buffer = nullptr;
+ if (mCachedBuffer && mCachedBuffer->getWidth() == sampledBounds.getWidth() &&
+ mCachedBuffer->getHeight() == sampledBounds.getHeight()) {
buffer = mCachedBuffer;
} else {
const uint32_t usage =
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
- sp<GraphicBuffer> graphicBuffer =
- new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(),
- PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
- const status_t bufferStatus = graphicBuffer->initCheck();
+ buffer = new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(),
+ PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
+ const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureSample: Buffer failed to allocate: %d",
bufferStatus);
- buffer = std::make_shared<
- renderengine::ExternalTexture>(graphicBuffer, mFlinger.getRenderEngine(),
- renderengine::ExternalTexture::Usage::WRITEABLE);
}
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
@@ -469,8 +465,8 @@
}
ALOGV("Sampling %zu descriptors", activeDescriptors.size());
- std::vector<float> lumas = sampleBuffer(buffer->getBuffer(), sampledBounds.leftTop(),
- activeDescriptors, orientation);
+ std::vector<float> lumas =
+ sampleBuffer(buffer, sampledBounds.leftTop(), activeDescriptors, orientation);
if (lumas.size() != activeDescriptors.size()) {
ALOGW("collected %zu median luma values for %zu descriptors", lumas.size(),
activeDescriptors.size());
@@ -481,6 +477,16 @@
activeDescriptors[d].listener->onSampleCollected(lumas[d]);
}
+ // Extend the lifetime of mCachedBuffer from the previous frame to here to ensure that:
+ // 1) The region sampling thread is the last owner of the buffer, and the freeing of the buffer
+ // happens in this thread, as opposed to the main thread.
+ // 2) The listener(s) receive their notifications prior to freeing the buffer.
+ if (mCachedBuffer != nullptr && mCachedBuffer != buffer) {
+ if (mFlinger.getRenderEngine().getRenderEngineType() ==
+ renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
+ mFlinger.getRenderEngine().unbindExternalTextureBuffer(mCachedBuffer->getId());
+ }
+ }
mCachedBuffer = buffer;
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
}
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 86632db..0defdb3 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -16,19 +16,17 @@
#pragma once
-#include <android-base/thread_annotations.h>
-#include <binder/IBinder.h>
-#include <renderengine/ExternalTexture.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/Rect.h>
-#include <utils/StrongPointer.h>
-
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <unordered_map>
+#include <android-base/thread_annotations.h>
+#include <binder/IBinder.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+#include <utils/StrongPointer.h>
#include "Scheduler/OneShotTimer.h"
namespace android {
@@ -124,8 +122,7 @@
std::mutex mSamplingMutex;
std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex);
- std::shared_ptr<renderengine::ExternalTexture> mCachedBuffer GUARDED_BY(mSamplingMutex) =
- nullptr;
+ sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ef5048b..2f8685b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -308,20 +308,6 @@
ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888;
bool SurfaceFlinger::useFrameRateApi;
-std::string getHwcServiceName() {
- char value[PROPERTY_VALUE_MAX] = {};
- property_get("debug.sf.hwc_service_name", value, "default");
- ALOGI("Using HWComposer service: '%s'", value);
- return std::string(value);
-}
-
-bool useTrebleTestingOverride() {
- char value[PROPERTY_VALUE_MAX] = {};
- property_get("debug.sf.treble_testing_override", value, "false");
- ALOGI("Treble testing override: '%s'", value);
- return std::string(value) == "true";
-}
-
std::string decodeDisplayColorSetting(DisplayColorSetting displayColorSetting) {
switch(displayColorSetting) {
case DisplayColorSetting::kManaged:
@@ -344,8 +330,6 @@
PermissionCache::checkPermission(sRotateSurfaceFlinger, pid, uid);
}
-SurfaceFlingerBE::SurfaceFlingerBE() : mHwcServiceName(getHwcServiceName()) {}
-
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
mInterceptor(mFactory.createSurfaceInterceptor()),
@@ -354,8 +338,11 @@
mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())),
mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()),
+ mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) {
+ ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
+
mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });
}
@@ -469,12 +456,13 @@
// comes online to attempt to read the property. The property is
// instead read after the boot animation
- if (useTrebleTestingOverride()) {
+ if (base::GetBoolProperty("debug.sf.treble_testing_override"s, false)) {
// Without the override SurfaceFlinger cannot connect to HIDL
// services that are not listed in the manifests. Considered
// deriving the setting from the set service name, but it
// would be brittle if the name that's not 'default' is used
// for production purposes later on.
+ ALOGI("Enabling Treble testing override");
android::hardware::details::setTrebleTestingOverride(true);
}
@@ -737,9 +725,8 @@
: renderengine::RenderEngine::ContextPriority::MEDIUM)
.build()));
mCompositionEngine->setTimeStats(mTimeStats);
- mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
+ mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
- ClientCache::getInstance().setRenderEngine(&getRenderEngine());
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
@@ -3705,6 +3692,7 @@
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
+ getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -4068,16 +4056,23 @@
}
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
- std::shared_ptr<renderengine::ExternalTexture> buffer;
+ sp<GraphicBuffer> buffer;
if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
- ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
- buffer = ClientCache::getInstance().get(s.cachedBuffer);
+ buffer = s.buffer;
+ bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ if (success) {
+ getRenderEngine().cacheExternalTextureBuffer(s.buffer);
+ success = ClientCache::getInstance()
+ .registerErasedRecipient(s.cachedBuffer,
+ wp<ClientCache::ErasedRecipient>(this));
+ if (!success) {
+ getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId());
+ }
+ }
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged) {
- buffer = std::make_shared<
- renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
- renderengine::ExternalTexture::Usage::READABLE);
+ buffer = s.buffer;
}
if (buffer) {
const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
@@ -5049,13 +5044,16 @@
#pragma clang diagnostic push
#pragma clang diagnostic error "-Wswitch-enum"
switch (static_cast<ISurfaceComposerTag>(code)) {
+ case ENABLE_VSYNC_INJECTIONS:
+ case INJECT_VSYNC:
+ if (!hasMockHwc()) return PERMISSION_DENIED;
+ [[fallthrough]];
// These methods should at minimum make sure that the client requested
// access to SF.
case BOOT_FINISHED:
case CLEAR_ANIMATION_FRAME_STATS:
case CREATE_DISPLAY:
case DESTROY_DISPLAY:
- case ENABLE_VSYNC_INJECTIONS:
case GET_ANIMATION_FRAME_STATS:
case OVERRIDE_HDR_TYPES:
case GET_HDR_CAPABILITIES:
@@ -5066,7 +5064,6 @@
case SET_AUTO_LOW_LATENCY_MODE:
case GET_GAME_CONTENT_TYPE_SUPPORT:
case SET_GAME_CONTENT_TYPE:
- case INJECT_VSYNC:
case SET_POWER_MODE:
case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES:
case SET_DISPLAY_CONTENT_SAMPLING_ENABLED:
@@ -5992,17 +5989,15 @@
const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
bufferStatus);
- const auto texture = std::make_shared<
- renderengine::ExternalTexture>(buffer, getRenderEngine(),
- renderengine::ExternalTexture::Usage::WRITEABLE);
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, texture,
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
false /* regionSampling */, grayscale, captureListener);
}
-status_t SurfaceFlinger::captureScreenCommon(
- RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers,
- const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
- bool grayscale, const sp<IScreenCaptureListener>& captureListener) {
+status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
+ TraverseLayersFunction traverseLayers,
+ sp<GraphicBuffer>& buffer, bool regionSampling,
+ bool grayscale,
+ const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
if (captureListener == nullptr) {
@@ -6035,6 +6030,15 @@
regionSampling, grayscale, captureResults);
});
+ // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
+ // Only do this when we're not doing region sampling, to allow the region sampling thread to
+ // manage buffer lifecycle itself.
+ if (!regionSampling &&
+ getRenderEngine().getRenderEngineType() ==
+ renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
+ getRenderEngine().unbindExternalTextureBuffer(buffer->getId());
+ }
+
captureResults.result = result;
captureListener->onScreenCaptureCompleted(captureResults);
}));
@@ -6042,10 +6046,11 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::renderScreenImplLocked(
- const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
- const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem,
- bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) {
+status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
+ TraverseLayersFunction traverseLayers,
+ const sp<GraphicBuffer>& buffer, bool forSystem,
+ bool regionSampling, bool grayscale,
+ ScreenCaptureResults& captureResults) {
ATRACE_CALL();
traverseLayers([&](Layer* layer) {
@@ -6053,7 +6058,7 @@
captureResults.capturedSecureLayers || (layer->isVisible() && layer->isSecure());
});
- const bool useProtected = buffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED;
+ const bool useProtected = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
// We allow the system server to take screenshots of secure layers for
// use in situations like the Screen-rotation animation and place
@@ -6063,7 +6068,7 @@
return PERMISSION_DENIED;
}
- captureResults.buffer = buffer->getBuffer();
+ captureResults.buffer = buffer;
captureResults.capturedDataspace = renderArea.getReqDataSpace();
const auto reqWidth = renderArea.getReqWidth();
@@ -6154,9 +6159,11 @@
base::unique_fd drawFence;
getRenderEngine().useProtectedContext(useProtected);
- const constexpr bool kUseFramebufferCache = false;
+ // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
+ const bool useFramebufferCache = getRenderEngine().getRenderEngineType() ==
+ renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED;
getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
- kUseFramebufferCache, std::move(bufferFence), &drawFence);
+ useFramebufferCache, std::move(bufferFence), &drawFence);
if (drawFence >= 0) {
sp<Fence> releaseFence = new Fence(dup(drawFence));
@@ -6421,6 +6428,10 @@
mOffscreenLayers.erase(layer);
}
+void SurfaceFlinger::bufferErased(const client_cache_t& clientCacheId) {
+ getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id);
+}
+
status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ,
float lightRadius) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index a242d8a..9135632 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -134,13 +134,7 @@
using DisplayColorSetting = compositionengine::OutputColorSetting;
-class SurfaceFlingerBE
-{
-public:
- SurfaceFlingerBE();
-
- const std::string mHwcServiceName; // "default" for real use, something else for testing.
-
+struct SurfaceFlingerBE {
FenceTimeline mGlCompositionDoneTimeline;
FenceTimeline mDisplayTimeline;
@@ -184,6 +178,7 @@
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
+ public ClientCache::ErasedRecipient,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback,
private ISchedulerCallback {
@@ -331,6 +326,9 @@
wp<Layer> fromHandle(const sp<IBinder>& handle);
wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock);
+ // Inherit from ClientCache::ErasedRecipient
+ void bufferErased(const client_cache_t& clientCacheId) override;
+
// If set, disables reusing client composition buffers. This can be set by
// debug.sf.disable_client_composition_cache
bool mDisableClientCompositionCache = false;
@@ -903,14 +901,12 @@
status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize,
ui::PixelFormat, bool allowProtected, bool grayscale,
const sp<IScreenCaptureListener>&);
- status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction,
- const std::shared_ptr<renderengine::ExternalTexture>&,
+ status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp<GraphicBuffer>&,
bool regionSampling, bool grayscale,
const sp<IScreenCaptureListener>&);
status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction,
- const std::shared_ptr<renderengine::ExternalTexture>&,
- bool forSystem, bool regionSampling, bool grayscale,
- ScreenCaptureResults&);
+ const sp<GraphicBuffer>&, bool forSystem, bool regionSampling,
+ bool grayscale, ScreenCaptureResults&);
sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock);
sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock);
@@ -1321,6 +1317,10 @@
SurfaceFlingerBE mBE;
std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
+ const std::string mHwcServiceName;
+
+ bool hasMockHwc() const { return mHwcServiceName == "mock"; }
+
/*
* Scheduler
*/
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 9f94c73..4ac096b 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -115,6 +115,7 @@
"android.hardware.power@1.1",
"android.hardware.power@1.2",
"android.hardware.power@1.3",
+ "android.hardware.power-V1-cpp",
"libcompositionengine_mocks",
"libcompositionengine",
"libframetimeline",
@@ -137,7 +138,6 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.2",
- "android.hardware.power-V1-cpp",
"libbase",
"libbinder",
"libcutils",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3042450..4e1c0c7 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -15,7 +15,6 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "renderengine/ExternalTexture.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wextra"
@@ -195,7 +194,7 @@
sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE;
- std::shared_ptr<renderengine::ExternalTexture> mCaptureScreenBuffer;
+ sp<GraphicBuffer> mCaptureScreenBuffer;
};
template <typename LayerCase>
@@ -244,15 +243,11 @@
// TODO: Eliminate expensive/real allocation if possible.
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
- mCaptureScreenBuffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(renderArea->getReqWidth(),
- renderArea->getReqHeight(),
- HAL_PIXEL_FORMAT_RGBA_8888, 1, usage,
- "screenshot"),
- *mRenderEngine, true);
+ mCaptureScreenBuffer = new GraphicBuffer(renderArea->getReqWidth(), renderArea->getReqHeight(),
+ HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot");
status_t result =
- mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
+ mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer.get(),
forSystem, regionSampling);
EXPECT_EQ(NO_ERROR, result);
@@ -345,8 +340,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillRepeatedly([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>&,
- const std::shared_ptr<renderengine::ExternalTexture>&,
- const bool, base::unique_fd&&, base::unique_fd*) -> status_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -394,8 +389,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillRepeatedly([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>&,
- const std::shared_ptr<renderengine::ExternalTexture>&,
- const bool, base::unique_fd&&, base::unique_fd*) -> status_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -630,8 +625,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -679,8 +674,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
@@ -756,8 +751,8 @@
EXPECT_CALL(*test->mRenderEngine, drawLayers)
.WillOnce([](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layerSettings,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t {
+ const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
+ base::unique_fd*) -> status_t {
EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance);
EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
displaySettings.physicalDisplay);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index d004b9d..63baf7d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -352,8 +352,8 @@
auto renderScreenImplLocked(const RenderArea& renderArea,
SurfaceFlinger::TraverseLayersFunction traverseLayers,
- const std::shared_ptr<renderengine::ExternalTexture>& buffer,
- bool forSystem, bool regionSampling) {
+ const sp<GraphicBuffer>& buffer, bool forSystem,
+ bool regionSampling) {
ScreenCaptureResults captureResults;
return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem,
regionSampling, false /* grayscale */,
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index 25001d3..ea1ce47 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -21,8 +21,6 @@
#include <gtest/gtest.h>
#include <gui/SurfaceComposerClient.h>
#include <log/log.h>
-#include <renderengine/ExternalTexture.h>
-#include <renderengine/mock/RenderEngine.h>
#include <utils/String8.h>
#include "TestableSurfaceFlinger.h"
@@ -101,7 +99,6 @@
TestableSurfaceFlinger mFlinger;
Hwc2::mock::Composer* mComposer = nullptr;
- renderengine::mock::RenderEngine mRenderEngine;
FenceToFenceTimeMap fenceFactory;
client_cache_t mClientCache;
@@ -109,12 +106,9 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
int32_t layerId = layer->getSequence();
- uint64_t bufferId = buffer->getBuffer()->getId();
+ uint64_t bufferId = buffer->getId();
uint64_t frameNumber = 5;
nsecs_t dequeueTime = 10;
nsecs_t postTime = 20;
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index b7917aa..09a1c2a 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -21,8 +21,6 @@
#include <gtest/gtest.h>
#include <gui/SurfaceComposerClient.h>
#include <log/log.h>
-#include <renderengine/ExternalTexture.h>
-#include <renderengine/mock/RenderEngine.h>
#include <utils/String8.h>
#include "TestableSurfaceFlinger.h"
@@ -101,7 +99,6 @@
TestableSurfaceFlinger mFlinger;
Hwc2::mock::Composer* mComposer = nullptr;
- renderengine::mock::RenderEngine mRenderEngine;
FenceToFenceTimeMap fenceFactory;
client_cache_t mClientCache;
@@ -122,10 +119,7 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence->signalForTest(12);
@@ -150,10 +144,7 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- const auto buffer1 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -162,10 +153,7 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- const auto buffer2 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
nsecs_t start = systemTime();
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
@@ -203,10 +191,8 @@
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence->signalForTest(12);
@@ -231,10 +217,8 @@
sp<BufferStateLayer> layer = createBufferStateLayer();
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -263,10 +247,8 @@
sp<Fence> fence(new Fence());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
- const auto buffer = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
+
layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -301,10 +283,7 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- const auto buffer1 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX);
@@ -312,10 +291,7 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- const auto buffer2 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
acquireFence2->signalForTest(12);
@@ -342,10 +318,7 @@
sp<Fence> fence1(new Fence());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
- const auto buffer1 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size());
@@ -354,10 +327,7 @@
sp<Fence> fence2(new Fence());
auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
- const auto buffer2 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
auto dropStartTime1 = systemTime();
layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0},
@@ -369,10 +339,7 @@
sp<Fence> fence3(new Fence());
auto acquireFence3 = fenceFactory.createFenceTimeForTest(fence3);
- const auto buffer3 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888,
- 1, 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer3{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
auto dropStartTime2 = systemTime();
layer->setBuffer(buffer3, fence3, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 2, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */);
@@ -412,11 +379,7 @@
std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames;
for (int i = 0; i < 10; i += 2) {
sp<Fence> fence1(new Fence());
- const auto buffer1 = std::make_shared<
- renderengine::ExternalTexture>(new GraphicBuffer(1, 1,
- HAL_PIXEL_FORMAT_RGBA_8888, 1,
- 0),
- mRenderEngine, false);
+ sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)};
layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt,
{/*vsyncId*/ 1, /*inputEventId*/ 0},
nullptr /* releaseBufferCallback */);