Merge "GpuStats: complete the coverage of ES1 usage tracking"
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 41718b2..d920a90 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -26,6 +26,7 @@
#ifndef ANDROID_BITMAP_H
#define ANDROID_BITMAP_H
+#include <stdbool.h>
#include <stdint.h>
#include <jni.h>
@@ -133,6 +134,84 @@
*/
int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap);
+#if __ANDROID_API__ >= 30
+
+// Note: these values match android.graphics.Bitmap#compressFormat.
+
+/**
+ * Specifies the formats that can be compressed to with
+ * {@link AndroidBitmap_compress}.
+ */
+enum AndroidBitmapCompressFormat {
+ /**
+ * Compress to the JPEG format. quality of 0 means
+ * compress for the smallest size. 100 means compress for max
+ * visual quality.
+ */
+ ANDROID_BITMAP_COMPRESS_FORMAT_JPEG = 0,
+ /**
+ * Compress to the PNG format. PNG is lossless, so quality is
+ * ignored.
+ */
+ ANDROID_BITMAP_COMPRESS_FORMAT_PNG = 1,
+ /**
+ * Compress to the WEBP lossy format. quality of 0 means
+ * compress for the smallest size. 100 means compress for max
+ * visual quality.
+ */
+ ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSY = 3,
+ /**
+ * Compress to the WEBP lossless format. quality refers to how
+ * much effort to put into compression. A value of 0 means to
+ * compress quickly, resulting in a relatively large file size.
+ * 100 means to spend more time compressing, resulting in a
+ * smaller file.
+ */
+ ANDROID_BITMAP_COMPRESS_FORMAT_WEBP_LOSSLESS = 4,
+};
+
+/**
+ * User-defined function for writing the output of compression.
+ *
+ * @param userContext Pointer to user-defined data passed to
+ * {@link AndroidBitmap_compress}.
+ * @param data Compressed data of |size| bytes to write.
+ * @param size Length in bytes of data to write.
+ * @return Whether the operation succeeded.
+ */
+typedef bool (*AndroidBitmap_compress_write_fn)(void* userContext,
+ const void* data,
+ size_t size) __INTRODUCED_IN(30);
+
+/**
+ * Compress |pixels| as described by |info|.
+ *
+ * @param info Description of the pixels to compress.
+ * @param dataspace {@link ADataSpace} describing the color space of the
+ * pixels.
+ * @param pixels Pointer to pixels to compress.
+ * @param format (@link AndroidBitmapCompressFormat} to compress to.
+ * @param quality Hint to the compressor, 0-100. The value is interpreted
+ * differently depending on the
+ * {@link AndroidBitmapCompressFormat}.
+ * @param userContext User-defined data which will be passed to the supplied
+ * {@link AndroidBitmap_compress_write_fn} each time it is
+ * called. May be null.
+ * @parm fn Function that writes the compressed data. Will be called each time
+ * the compressor has compressed more data that is ready to be
+ * written. May be called more than once for each call to this method.
+ * May not be null.
+ * @return AndroidBitmap functions result code.
+ */
+int AndroidBitmap_compress(const AndroidBitmapInfo* info,
+ int32_t dataspace,
+ const void* pixels,
+ int32_t format, int32_t quality,
+ void* userContext,
+ AndroidBitmap_compress_write_fn fn) __INTRODUCED_IN(30);
+
+#endif // __ANDROID_API__ >= 30
+
#ifdef __cplusplus
}
#endif
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
index 50daaba..4b6446c 100644
--- a/include/android/imagedecoder.h
+++ b/include/android/imagedecoder.h
@@ -143,23 +143,20 @@
int AImageDecoder_setAndroidBitmapFormat(AImageDecoder*,
int32_t format) __INTRODUCED_IN(30);
-/*
- * Choose the desired output format.
+/**
+ * Specify whether the output's pixels should be unpremultiplied.
*
- * Must be one of:
- * {@link ANDROID_BITMAP_FLAGS_ALPHA_PREMUL}
- * {@link ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE}
- * {@link ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL}
+ * By default, the decoder will premultiply the pixels, if they have alpha. Pass
+ * false to this method to leave them unpremultiplied. This has no effect on an
+ * opaque image.
*
- * Note: An OPAQUE image may be set to any of them.
- * A non-OPAQUE image may not be set to OPAQUE
- *
+ * @param required Pass true to leave the pixels unpremultiplied.
* @return - {@link ANDROID_IMAGE_DECODER_SUCCESS} on success
* - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION} if the conversion
* is not possible
* - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} for bad parameters
*/
-int AImageDecoder_setAlphaFlags(AImageDecoder*, int alphaFlags) __INTRODUCED_IN(30);
+int AImageDecoder_setUnpremultipliedRequired(AImageDecoder*, bool required) __INTRODUCED_IN(30);
/**
* Specify the output size for a decoded image.
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index ebd08b2..daaaa5a 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -90,8 +90,7 @@
aidl_interface {
name: "IBinderVendorDoubleLoadTest",
- // TODO(b/119771576): only vendor is needed
- vendor_available: true,
+ vendor: true,
srcs: [
"IBinderVendorDoubleLoadTest.aidl",
],
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index ca0d4b5..42c6e15 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -30,6 +30,8 @@
#include <aidl/android/hardware/graphics/common/XyColor.h>
#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+namespace android {
+
/**
* Define equality operators for Stable AIDL types.
*/
@@ -210,8 +212,6 @@
return !(lhs == rhs);
}
-namespace android {
-
namespace gralloc4 {
#define GRALLOC4_STANDARD_METADATA_TYPE "android.hardware.graphics.common.StandardMetadataType"
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f88ddf1..9674e54 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -109,7 +109,7 @@
void BLASTBufferQueue::processNextBufferLocked() {
ATRACE_CALL();
- if (mNumFrameAvailable == 0) {
+ if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) {
return;
}
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 04493f0..abc64bd 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -66,6 +66,7 @@
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.3-command-buffer",
+ "android.hardware.graphics.composer@2.4-command-buffer",
"libdvr_headers",
"libsurfaceflinger_headers",
]
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 8fa35d8..9a7eabd 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -79,6 +79,7 @@
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.3-command-buffer",
+ "android.hardware.graphics.composer@2.4-command-buffer",
],
export_static_lib_headers: [
"libcompositionengine",
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 18477bb..42d9875 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -35,6 +35,7 @@
"android.hardware.graphics.composer@2.1-command-buffer",
"android.hardware.graphics.composer@2.2-command-buffer",
"android.hardware.graphics.composer@2.3-command-buffer",
+ "android.hardware.graphics.composer@2.4-command-buffer",
"libsurfaceflinger_headers",
],
}
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 6892dd8..9d8f31b 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -1337,8 +1337,7 @@
uint16_t length = 0;
while (!isEmpty()) {
- auto command_2_1 = reinterpret_cast<V2_1::IComposerClient::Command*>(&command);
- if (!beginCommand(command_2_1, &length)) {
+ if (!beginCommand(&command, &length)) {
break;
}
@@ -1365,6 +1364,9 @@
case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
parsed = parseSetPresentOrValidateDisplayResult(length);
break;
+ case IComposerClient::Command::SET_CLIENT_TARGET_PROPERTY:
+ parsed = parseSetClientTargetProperty(length);
+ break;
default:
parsed = false;
break;
@@ -1502,6 +1504,15 @@
return true;
}
+bool CommandReader::parseSetClientTargetProperty(uint16_t length) {
+ if (length != CommandWriterBase::kSetClientTargetPropertyLength || !mCurrentReturnData) {
+ return false;
+ }
+ mCurrentReturnData->clientTargetProperty.pixelFormat = static_cast<PixelFormat>(readSigned());
+ mCurrentReturnData->clientTargetProperty.dataspace = static_cast<Dataspace>(readSigned());
+ return true;
+}
+
void CommandReader::resetData()
{
mErrors.clear();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 301f54f..6f0f38a 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -29,7 +29,7 @@
#include <android/hardware/graphics/common/1.1/types.h>
#include <android/hardware/graphics/composer/2.4/IComposer.h>
#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
-#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
+#include <composer-command-buffer/2.4/ComposerCommandBuffer.h>
#include <gui/HdrMetadata.h>
#include <math/mat4.h>
#include <ui/DisplayedFrameStats.h>
@@ -63,8 +63,8 @@
using V2_1::Display;
using V2_1::Error;
using V2_1::Layer;
-using V2_3::CommandReaderBase;
-using V2_3::CommandWriterBase;
+using V2_4::CommandReaderBase;
+using V2_4::CommandWriterBase;
using V2_4::IComposer;
using V2_4::IComposerCallback;
using V2_4::IComposerClient;
@@ -280,6 +280,7 @@
bool parseSetPresentFence(uint16_t length);
bool parseSetReleaseFences(uint16_t length);
bool parseSetPresentOrValidateDisplayResult(uint16_t length);
+ bool parseSetClientTargetProperty(uint16_t length);
struct ReturnData {
uint32_t displayRequests = 0;
@@ -296,6 +297,13 @@
std::vector<int> releaseFences;
uint32_t presentOrValidateState;
+
+ // Composer 2.4 implementation can return a client target property
+ // structure to indicate the client target properties that hardware
+ // composer requests. The composer client must change the client target
+ // properties to match this request.
+ IComposerClient::ClientTargetProperty clientTargetProperty{PixelFormat::RGBA_8888,
+ Dataspace::UNKNOWN};
};
std::vector<CommandError> mErrors;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 8219a7d..abf0cd6 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -43,6 +43,9 @@
namespace {
bool isLayerActive(const Layer& layer, const LayerInfo& info, nsecs_t threshold) {
+ if (layer.getFrameRate() > .0f) {
+ return layer.isVisible();
+ }
return layer.isVisible() && info.getLastUpdatedTime() >= threshold;
}
@@ -117,11 +120,32 @@
// Layers should be organized by priority
ALOGD("Layer has priority: %d", priority);
}
+ }
+ }
+ }
+
+ for (const auto& [weakLayer, info] : activeLayers()) {
+ const bool recent = info->isRecentlyActive(now);
+ auto layer = weakLayer.promote();
+ // Only use the layer if the reference still exists.
+ if (layer || CC_UNLIKELY(mTraceEnabled)) {
+ float refreshRate = 0.f;
+ // Default content refresh rate is only used when dealing with recent layers.
+ if (recent) {
+ refreshRate = info->getRefreshRate(now);
+ }
+ // Check if frame rate was set on layer.
+ float frameRate = layer->getFrameRate();
+ if (frameRate > 0.f) {
+ // Override content detection refresh rate, if it was set.
+ refreshRate = frameRate;
+ }
+ if (refreshRate > maxRefreshRate) {
maxRefreshRate = refreshRate;
}
if (CC_UNLIKELY(mTraceEnabled)) {
- trace(activeLayer, std::round(refreshRate));
+ trace(weakLayer, std::round(refreshRate));
}
}
}
@@ -175,6 +199,22 @@
mActiveLayersEnd = 0;
}
+bool LayerHistory::hasClientSpecifiedFrameRate() {
+ std::lock_guard lock(mLock);
+ for (const auto& [weakLayer, info] : activeLayers()) {
+ auto layer = weakLayer.promote();
+ if (layer) {
+ float frameRate = layer->getFrameRate();
+ // Found a layer that has a frame rate set on it.
+ if (fabs(frameRate) > 0.f) {
+ return true;
+ }
+ }
+ }
+ // Did not find any layers that have frame rate.
+ return false;
+}
+
} // namespace android::scheduler::impl
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
index 188fa64..f217134 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.h
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -53,6 +53,9 @@
virtual Summary summarize(nsecs_t now) = 0;
virtual void clear() = 0;
+
+ // Checks whether any of the active layers have a desired frame rate bit set on them.
+ virtual bool hasClientSpecifiedFrameRate() = 0;
};
namespace impl {
@@ -75,6 +78,10 @@
void clear() override;
+ // Traverses all active layers and checks whether any of them have a desired frame
+ // rate bit set on them.
+ bool hasClientSpecifiedFrameRate() override;
+
private:
friend class android::scheduler::LayerHistoryTest;
friend TestableScheduler;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index c96eba4..0b645c4 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -422,18 +422,20 @@
}
void Scheduler::notifyTouchEvent() {
- if (mTouchTimer) {
- mTouchTimer->reset();
- }
-
- if (mSupportKernelTimer && mIdleTimer) {
- mIdleTimer->reset();
- }
-
// Touch event will boost the refresh rate to performance.
- // Clear Layer History to get fresh FPS detection
- if (mLayerHistory) {
+ // Clear Layer History to get fresh FPS detection.
+ // NOTE: Instead of checking all the layers, we should be checking the layer
+ // that is currently on top. b/142507166 will give us this capability.
+ if (mLayerHistory && !mLayerHistory->hasClientSpecifiedFrameRate()) {
mLayerHistory->clear();
+
+ if (mTouchTimer) {
+ mTouchTimer->reset();
+ }
+
+ if (mSupportKernelTimer && mIdleTimer) {
+ mIdleTimer->reset();
+ }
}
}
@@ -533,25 +535,31 @@
return mRefreshRateConfigs.getCurrentRefreshRate().configId;
}
- // If Display Power is not in normal operation we want to be in performance mode.
- // When coming back to normal mode, a grace period is given with DisplayPowerTimer
- if (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
- }
+ // If the layer history doesn't have the frame rate specified, use the old path. NOTE:
+ // if we remove the kernel idle timer, and use our internal idle timer, this code will have to
+ // be refactored.
+ if (!mLayerHistory->hasClientSpecifiedFrameRate()) {
+ // If Display Power is not in normal operation we want to be in performance mode.
+ // When coming back to normal mode, a grace period is given with DisplayPowerTimer
+ if (!mFeatures.isDisplayPowerStateNormal ||
+ mFeatures.displayPowerTimer == TimerState::Reset) {
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ }
- // As long as touch is active we want to be in performance mode
- if (mFeatures.touch == TouchState::Active) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
- }
+ // As long as touch is active we want to be in performance mode
+ if (mFeatures.touch == TouchState::Active) {
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ }
- // If timer has expired as it means there is no new content on the screen
- if (mFeatures.idleTimer == TimerState::Expired) {
- return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId;
- }
+ // If timer has expired as it means there is no new content on the screen
+ if (mFeatures.idleTimer == TimerState::Expired) {
+ return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId;
+ }
- // If content detection is off we choose performance as we don't know the content fps
- if (mFeatures.contentDetection == ContentDetectionState::Off) {
- return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ // If content detection is off we choose performance as we don't know the content fps
+ if (mFeatures.contentDetection == ContentDetectionState::Off) {
+ return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+ }
}
// Content detection is on, find the appropriate refresh rate with minimal error
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
index 5824e58..1d3fed8 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp
@@ -780,6 +780,15 @@
return V2_4::Error::UNSUPPORTED;
}
+V2_4::Error FakeComposerClient::validateDisplay_2_4(
+ Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
+ std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
+ uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
+ std::vector<uint32_t>* /*outRequestMasks*/,
+ IComposerClient::ClientTargetProperty* /*outClientTargetProperty*/) {
+ return V2_4::Error::NONE;
+}
+
//////////////////////////////////////////////////////////////////
void FakeComposerClient::requestVSync(uint64_t vsyncTime) {
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
index f9ff2bf..a524850 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
@@ -251,6 +251,12 @@
Display display,
std::vector<IComposerClient::ContentType>* outSupportedContentTypes) override;
V2_4::Error setContentType(Display display, IComposerClient::ContentType type) override;
+ V2_4::Error validateDisplay_2_4(
+ Display display, std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks,
+ IComposerClient::ClientTargetProperty* outClientTargetProperty) override;
void setClient(ComposerClient* client);