Remove the redundant getProcessFreezeInfo() am: 4e678b9830
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/15842844
Change-Id: Id852ed41260cc0cabbe6efe03baec4b1ae8ee5d5
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index d54de49..7f0cac5 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -343,80 +343,6 @@
return nullptr;
}
-bool GraphicsEnv::checkAngleRules(void* so) {
- auto manufacturer = base::GetProperty("ro.product.manufacturer", "UNSET");
- auto model = base::GetProperty("ro.product.model", "UNSET");
-
- auto ANGLEGetFeatureSupportUtilAPIVersion =
- (fpANGLEGetFeatureSupportUtilAPIVersion)dlsym(so,
- "ANGLEGetFeatureSupportUtilAPIVersion");
-
- if (!ANGLEGetFeatureSupportUtilAPIVersion) {
- ALOGW("Cannot find ANGLEGetFeatureSupportUtilAPIVersion function");
- return false;
- }
-
- // Negotiate the interface version by requesting most recent known to the platform
- unsigned int versionToUse = CURRENT_ANGLE_API_VERSION;
- if (!(ANGLEGetFeatureSupportUtilAPIVersion)(&versionToUse)) {
- ALOGW("Cannot use ANGLE feature-support library, it is older than supported by EGL, "
- "requested version %u",
- versionToUse);
- return false;
- }
-
- // Add and remove versions below as needed
- bool useAngle = false;
- switch (versionToUse) {
- case 2: {
- ALOGV("Using version %d of ANGLE feature-support library", versionToUse);
- void* rulesHandle = nullptr;
- int rulesVersion = 0;
- void* systemInfoHandle = nullptr;
-
- // Get the symbols for the feature-support-utility library:
-#define GET_SYMBOL(symbol) \
- fp##symbol symbol = (fp##symbol)dlsym(so, #symbol); \
- if (!symbol) { \
- ALOGW("Cannot find " #symbol " in ANGLE feature-support library"); \
- break; \
- }
- GET_SYMBOL(ANGLEAndroidParseRulesString);
- GET_SYMBOL(ANGLEGetSystemInfo);
- GET_SYMBOL(ANGLEAddDeviceInfoToSystemInfo);
- GET_SYMBOL(ANGLEShouldBeUsedForApplication);
- GET_SYMBOL(ANGLEFreeRulesHandle);
- GET_SYMBOL(ANGLEFreeSystemInfoHandle);
-
- // Parse the rules, obtain the SystemInfo, and evaluate the
- // application against the rules:
- if (!(ANGLEAndroidParseRulesString)(mRulesBuffer.data(), &rulesHandle, &rulesVersion)) {
- ALOGW("ANGLE feature-support library cannot parse rules file");
- break;
- }
- if (!(ANGLEGetSystemInfo)(&systemInfoHandle)) {
- ALOGW("ANGLE feature-support library cannot obtain SystemInfo");
- break;
- }
- if (!(ANGLEAddDeviceInfoToSystemInfo)(manufacturer.c_str(), model.c_str(),
- systemInfoHandle)) {
- ALOGW("ANGLE feature-support library cannot add device info to SystemInfo");
- break;
- }
- useAngle = (ANGLEShouldBeUsedForApplication)(rulesHandle, rulesVersion,
- systemInfoHandle, mAngleAppName.c_str());
- (ANGLEFreeRulesHandle)(rulesHandle);
- (ANGLEFreeSystemInfoHandle)(systemInfoHandle);
- } break;
-
- default:
- ALOGW("Version %u of ANGLE feature-support library is NOT supported.", versionToUse);
- }
-
- ALOGV("Close temporarily-loaded ANGLE opt-in/out logic");
- return useAngle;
-}
-
bool GraphicsEnv::shouldUseAngle(std::string appName) {
if (appName != mAngleAppName) {
// Make sure we are checking the app we were init'ed for
@@ -444,31 +370,20 @@
const char* ANGLE_PREFER_ANGLE = "angle";
const char* ANGLE_PREFER_NATIVE = "native";
+ mUseAngle = NO;
if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
ALOGV("User set \"Developer Options\" to force the use of ANGLE");
mUseAngle = YES;
} else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
ALOGV("User set \"Developer Options\" to force the use of Native");
- mUseAngle = NO;
} else {
- // The "Developer Options" value wasn't set to force the use of ANGLE. Need to temporarily
- // load ANGLE and call the updatable opt-in/out logic:
- void* featureSo = loadLibrary("feature_support");
- if (featureSo) {
- ALOGV("loaded ANGLE's opt-in/out logic from namespace");
- mUseAngle = checkAngleRules(featureSo) ? YES : NO;
- dlclose(featureSo);
- featureSo = nullptr;
- } else {
- ALOGV("Could not load the ANGLE opt-in/out logic, cannot use ANGLE.");
- }
+ ALOGV("User set invalid \"Developer Options\": '%s'", mAngleDeveloperOptIn.c_str());
}
}
void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
const std::string developerOptIn,
- const std::vector<std::string> eglFeatures, const int rulesFd,
- const long rulesOffset, const long rulesLength) {
+ const std::vector<std::string> eglFeatures) {
if (mUseAngle != UNKNOWN) {
// We've already figured out an answer for this app, so just return.
ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", appName.c_str(),
@@ -485,22 +400,6 @@
ALOGV("setting ANGLE application opt-in to '%s'", developerOptIn.c_str());
mAngleDeveloperOptIn = developerOptIn;
- lseek(rulesFd, rulesOffset, SEEK_SET);
- mRulesBuffer = std::vector<char>(rulesLength + 1);
- ssize_t numBytesRead = read(rulesFd, mRulesBuffer.data(), rulesLength);
- if (numBytesRead < 0) {
- ALOGE("Cannot read rules file: numBytesRead = %zd", numBytesRead);
- numBytesRead = 0;
- } else if (numBytesRead == 0) {
- ALOGW("Empty rules file");
- }
- if (numBytesRead != rulesLength) {
- ALOGW("Did not read all of the necessary bytes from the rules file."
- "expected: %ld, got: %zd",
- rulesLength, numBytesRead);
- }
- mRulesBuffer[numBytesRead] = '\0';
-
// Update the current status of whether we should use ANGLE or not
updateUseAngle();
}
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 900fc49..56d1139 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -97,8 +97,7 @@
// in the search path must have a '!' after the zip filename, e.g.
// /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
- const std::vector<std::string> eglFeatures, const int rulesFd,
- const long rulesOffset, const long rulesLength);
+ const std::vector<std::string> eglFeatures);
// Get the ANGLE driver namespace.
android_namespace_t* getAngleNamespace();
// Get the app name for ANGLE debug message.
@@ -129,8 +128,6 @@
// Load requested ANGLE library.
void* loadLibrary(std::string name);
- // Check ANGLE support with the rules.
- bool checkAngleRules(void* so);
// Update whether ANGLE should be used.
void updateUseAngle();
// Link updatable driver namespace with llndk and vndk-sp libs.
@@ -159,8 +156,6 @@
std::string mAngleDeveloperOptIn;
// ANGLE EGL features;
std::vector<std::string> mAngleEglFeatures;
- // ANGLE rules.
- std::vector<char> mRulesBuffer;
// Use ANGLE flag.
UseAngle mUseAngle = UNKNOWN;
// Vulkan debug layers libs.
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index f7ec8ef..94e1ae1 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -118,12 +118,12 @@
}
void BLASTBufferItemConsumer::setBlastBufferQueue(BLASTBufferQueue* blastbufferqueue) {
- Mutex::Autolock lock(mMutex);
+ std::scoped_lock lock(mBufferQueueMutex);
mBLASTBufferQueue = blastbufferqueue;
}
void BLASTBufferItemConsumer::onSidebandStreamChanged() {
- Mutex::Autolock lock(mMutex);
+ std::scoped_lock lock(mBufferQueueMutex);
if (mBLASTBufferQueue != nullptr) {
sp<NativeHandle> stream = getSidebandStream();
mBLASTBufferQueue->setSidebandStream(stream);
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index ea9b1c6..6c5b2aa 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -62,11 +62,12 @@
uint64_t mCurrentFrameNumber = 0;
Mutex mMutex;
+ std::mutex mBufferQueueMutex;
ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex);
std::queue<uint64_t> mDisconnectEvents GUARDED_BY(mMutex);
bool mCurrentlyConnected GUARDED_BY(mMutex);
bool mPreviouslyConnected GUARDED_BY(mMutex);
- BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mMutex);
+ BLASTBufferQueue* mBLASTBufferQueue GUARDED_BY(mBufferQueueMutex);
};
class BLASTBufferQueue
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 3c59f11..94023e6 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -424,14 +424,28 @@
return fenceFd;
}
-bool SkiaGLRenderEngine::waitFence(base::unique_fd fenceFd) {
+void SkiaGLRenderEngine::waitFence(base::borrowed_fd fenceFd) {
+ if (fenceFd.get() >= 0 && !waitGpuFence(fenceFd)) {
+ ATRACE_NAME("SkiaGLRenderEngine::waitFence");
+ sync_wait(fenceFd.get(), -1);
+ }
+}
+
+bool SkiaGLRenderEngine::waitGpuFence(base::borrowed_fd fenceFd) {
if (!gl::GLExtensions::getInstance().hasNativeFenceSync() ||
!gl::GLExtensions::getInstance().hasWaitSync()) {
return false;
}
+ // Duplicate the fence for passing to eglCreateSyncKHR.
+ base::unique_fd fenceDup(dup(fenceFd.get()));
+ if (fenceDup.get() < 0) {
+ ALOGE("failed to create duplicate fence fd: %d", fenceDup.get());
+ return false;
+ }
+
// release the fd and transfer the ownership to EGLSync
- EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceFd.release(), EGL_NONE};
+ EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fenceDup.release(), EGL_NONE};
EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) {
ALOGE("failed to create EGL native fence sync: %#x", eglGetError());
@@ -726,14 +740,6 @@
return NO_ERROR;
}
- if (bufferFence.get() >= 0) {
- // Duplicate the fence for passing to waitFence.
- base::unique_fd bufferFenceDup(dup(bufferFence.get()));
- if (bufferFenceDup < 0 || !waitFence(std::move(bufferFenceDup))) {
- ATRACE_NAME("Waiting before draw");
- sync_wait(bufferFence.get(), -1);
- }
- }
if (buffer == nullptr) {
ALOGE("No output buffer provided. Aborting GPU composition.");
return BAD_VALUE;
@@ -758,6 +764,9 @@
true, mTextureCleanupMgr);
}
+ // wait on the buffer to be ready to use prior to using it
+ waitFence(bufferFence);
+
const ui::Dataspace dstDataspace =
mUseColorManagement ? display.outputDataspace : ui::Dataspace::V0_SRGB_LINEAR;
sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
@@ -1014,6 +1023,12 @@
false, mTextureCleanupMgr);
}
+ // if the layer's buffer has a fence, then we must must respect the fence prior to using
+ // the buffer.
+ if (layer->source.buffer.fence != nullptr) {
+ waitFence(layer->source.buffer.fence->get());
+ }
+
// isOpaque means we need to ignore the alpha in the image,
// replacing it with the alpha specified by the LayerSettings. See
// https://developer.android.com/reference/android/view/SurfaceControl.Builder#setOpaque(boolean)
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index a852bbc..238ad8f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -99,7 +99,10 @@
inline GrDirectContext* getActiveGrContext() const;
base::unique_fd flush();
- bool waitFence(base::unique_fd fenceFd);
+ // waitFence attempts to wait in the GPU, and if unable to waits on the CPU instead.
+ void waitFence(base::borrowed_fd fenceFd);
+ bool waitGpuFence(base::borrowed_fd fenceFd);
+
void initCanvas(SkCanvas* canvas, const DisplaySettings& display);
void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect,
const ShadowSettings& shadowSettings);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 75dd51c..d8cead5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -820,11 +820,7 @@
}
bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
- sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
- if (handle == nullptr) {
- return false;
- }
- sp<Layer> relative = handle->owner.promote();
+ sp<Layer> relative = fromHandle(relativeToHandle).promote();
if (relative == nullptr) {
return false;
}
@@ -1610,8 +1606,7 @@
bool Layer::reparent(const sp<IBinder>& newParentHandle) {
sp<Layer> newParent;
if (newParentHandle != nullptr) {
- auto handle = static_cast<Handle*>(newParentHandle.get());
- newParent = handle->owner.promote();
+ newParent = fromHandle(newParentHandle).promote();
if (newParent == nullptr) {
ALOGE("Unable to promote Layer handle");
return false;
@@ -1986,24 +1981,10 @@
mDrawingParent = mCurrentParent;
}
-static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) {
- if (weakBinderHandle == nullptr) {
- return nullptr;
- }
- sp<IBinder> binderHandle = weakBinderHandle.promote();
- if (binderHandle == nullptr) {
- return nullptr;
- }
- sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get());
- if (handle == nullptr) {
- return nullptr;
- }
- return handle->owner;
-}
void Layer::setInputInfo(const InputWindowInfo& info) {
mDrawingState.inputInfo = info;
- mDrawingState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle);
+ mDrawingState.touchableRegionCrop = fromHandle(info.touchableRegionCropHandle.promote());
mDrawingState.modified = true;
mFlinger->mInputInfoChanged = true;
setTransactionFlags(eTransactionNeeded);
@@ -2562,6 +2543,23 @@
mFlinger->mNumClones++;
}
+const String16 Layer::Handle::kDescriptor = String16("android.Layer.Handle");
+
+wp<Layer> Layer::fromHandle(const sp<IBinder>& handleBinder) {
+ if (handleBinder == nullptr) {
+ return nullptr;
+ }
+
+ BBinder* b = handleBinder->localBinder();
+ if (b == nullptr || b->getInterfaceDescriptor() != Handle::kDescriptor) {
+ return nullptr;
+ }
+
+ // We can safely cast this binder since its local and we verified its interface descriptor.
+ sp<Handle> handle = static_cast<Handle*>(handleBinder.get());
+ return handle->owner;
+}
+
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 59f5b0d..8905548 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -289,16 +289,17 @@
class LayerCleaner {
sp<SurfaceFlinger> mFlinger;
sp<Layer> mLayer;
+ BBinder* mHandle;
protected:
~LayerCleaner() {
// destroy client resources
- mFlinger->onHandleDestroyed(mLayer);
+ mFlinger->onHandleDestroyed(mHandle, mLayer);
}
public:
- LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
- : mFlinger(flinger), mLayer(layer) {}
+ LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer, BBinder* handle)
+ : mFlinger(flinger), mLayer(layer), mHandle(handle) {}
};
/*
@@ -312,11 +313,15 @@
class Handle : public BBinder, public LayerCleaner {
public:
Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
- : LayerCleaner(flinger, layer), owner(layer) {}
+ : LayerCleaner(flinger, layer, this), owner(layer) {}
+ const String16& getInterfaceDescriptor() const override { return kDescriptor; }
+ static const String16 kDescriptor;
wp<Layer> owner;
};
+ static wp<Layer> fromHandle(const sp<IBinder>& handle);
+
explicit Layer(const LayerCreationArgs& args);
virtual ~Layer();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 0334d70..73b7b63 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -911,7 +911,10 @@
int RefreshRateConfigs::getFrameRateDivider(Fps displayFrameRate, Fps layerFrameRate) {
// This calculation needs to be in sync with the java code
// in DisplayManagerService.getDisplayInfoForFrameRateOverride
- constexpr float kThreshold = 0.1f;
+
+ // The threshold must be smaller than 0.001 in order to differentiate
+ // between the fractional pairs (e.g. 59.94 and 60).
+ constexpr float kThreshold = 0.0009f;
const auto numPeriods = displayFrameRate.getValue() / layerFrameRate.getValue();
const auto numPeriodsRounded = std::round(numPeriods);
if (std::abs(numPeriods - numPeriodsRounded) > kThreshold) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e0b3640..64ad178 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -386,6 +386,13 @@
}
const auto modeId = *mFeatures.modeId;
+ // If the modeId is not the current mode, this means that a
+ // mode change is in progress. In that case we shouldn't dispatch an event
+ // as it will be dispatched when the current mode changes.
+ if (mRefreshRateConfigs.getCurrentRefreshRate().getModeId() != modeId) {
+ return;
+ }
+
const auto vsyncPeriod = mRefreshRateConfigs.getRefreshRateFromModeId(modeId).getVsyncPeriod();
// If there is no change from cached mode, there is no need to dispatch an event
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 230810c..fe43a20 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3611,7 +3611,7 @@
sp<Layer> layer = nullptr;
if (s.surface) {
- layer = fromHandleLocked(s.surface).promote();
+ layer = fromHandle(s.surface).promote();
} else if (s.hasBufferChanges()) {
ALOGW("Transaction with buffer, but no Layer?");
continue;
@@ -3778,7 +3778,7 @@
setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
postTime, permissions, listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
- if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
+ if (const auto layer = fromHandle(state.state.surface).promote(); layer) {
mScheduler->recordLayerHistory(layer.get(),
isAutoTimestamp ? 0 : desiredPresentTime,
LayerHistory::LayerUpdateType::AnimationTX);
@@ -3933,13 +3933,11 @@
if (what & layer_state_t::eLayerCreated) {
layer = handleLayerCreatedLocked(s.surface);
if (layer) {
- // put the created layer into mLayersByLocalBinderToken.
- mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
flags |= eTransactionNeeded | eTraversalNeeded;
mLayersAdded = true;
}
} else {
- layer = fromHandleLocked(s.surface).promote();
+ layer = fromHandle(s.surface).promote();
}
} else {
// The client may provide us a null handle. Treat it as if the layer was removed.
@@ -4267,7 +4265,7 @@
{
Mutex::Autolock _l(mStateLock);
- mirrorFrom = fromHandleLocked(mirrorFromHandle).promote();
+ mirrorFrom = fromHandle(mirrorFromHandle).promote();
if (!mirrorFrom) {
return NAME_NOT_FOUND;
}
@@ -4465,7 +4463,7 @@
setTransactionFlags(eTransactionNeeded);
}
-void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer) {
+void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer) {
Mutex::Autolock lock(mStateLock);
// If a layer has a parent, we allow it to out-live it's handle
// with the idea that the parent holds a reference and will eventually
@@ -4476,17 +4474,7 @@
mCurrentState.layersSortedByZ.remove(layer);
}
markLayerPendingRemovalLocked(layer);
-
- auto it = mLayersByLocalBinderToken.begin();
- while (it != mLayersByLocalBinderToken.end()) {
- if (it->second == layer) {
- mBufferCountTracker.remove(it->first->localBinder());
- it = mLayersByLocalBinderToken.erase(it);
- } else {
- it++;
- }
- }
-
+ mBufferCountTracker.remove(handle);
layer.clear();
}
@@ -6089,7 +6077,7 @@
{
Mutex::Autolock lock(mStateLock);
- parent = fromHandleLocked(args.layerHandle).promote();
+ parent = fromHandle(args.layerHandle).promote();
if (parent == nullptr || parent->isRemovedFromCurrentState()) {
ALOGE("captureLayers called with an invalid or removed parent");
return NAME_NOT_FOUND;
@@ -6120,7 +6108,7 @@
reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY);
for (const auto& handle : args.excludeHandles) {
- sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
+ sp<Layer> excludeLayer = fromHandle(handle).promote();
if (excludeLayer != nullptr) {
excludeLayers.emplace(excludeLayer);
} else {
@@ -6616,24 +6604,8 @@
}
}
-wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
- Mutex::Autolock _l(mStateLock);
- return fromHandleLocked(handle);
-}
-
-wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) const {
- BBinder* b = nullptr;
- if (handle) {
- b = handle->localBinder();
- }
- if (b == nullptr) {
- return nullptr;
- }
- auto it = mLayersByLocalBinderToken.find(b);
- if (it != mLayersByLocalBinderToken.end()) {
- return it->second;
- }
- return nullptr;
+wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) const {
+ return Layer::fromHandle(handle);
}
void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
@@ -6938,7 +6910,7 @@
sp<Layer> parent;
bool allowAddRoot = state->addToRoot;
if (state->initialParent != nullptr) {
- parent = fromHandleLocked(state->initialParent.promote()).promote();
+ parent = fromHandle(state->initialParent.promote()).promote();
if (parent == nullptr) {
ALOGE("Invalid parent %p", state->initialParent.unsafe_get());
allowAddRoot = false;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 380f444..c3d837e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -327,8 +327,7 @@
// Returns nullptr if the handle does not point to an existing layer.
// Otherwise, returns a weak reference so that callers off the main-thread
// won't accidentally hold onto the last strong reference.
- wp<Layer> fromHandle(const sp<IBinder>& handle);
- wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock);
+ wp<Layer> fromHandle(const sp<IBinder>& handle) const;
// If set, disables reusing client composition buffers. This can be set by
// debug.sf.disable_client_composition_cache
@@ -898,7 +897,7 @@
// called when all clients have released all their references to
// this layer meaning it is entirely safe to destroy all
// resources associated to this layer.
- void onHandleDestroyed(sp<Layer>& layer);
+ void onHandleDestroyed(BBinder* handle, sp<Layer>& layer);
void markLayerPendingRemovalLocked(const sp<Layer>& layer);
// add a layer to SurfaceFlinger
@@ -1290,8 +1289,6 @@
std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal;
} mVirtualDisplayIdGenerators;
- std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
-
// don't use a lock for these, we don't care
int mDebugRegion = 0;
bool mDebugDisableHWC = false;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 23ab7c8..837b2e8 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -183,12 +183,9 @@
return NO_ERROR;
}
-const sp<const Layer> SurfaceInterceptor::getLayer(const wp<const IBinder>& weakHandle) const {
- const sp<const IBinder>& handle(weakHandle.promote());
- const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
- const sp<const Layer> layer(layerHandle->owner.promote());
- // layer could be a nullptr at this point
- return layer;
+const sp<const Layer> SurfaceInterceptor::getLayer(const wp<IBinder>& weakHandle) const {
+ sp<IBinder> handle = weakHandle.promote();
+ return Layer::fromHandle(handle).promote();
}
int32_t SurfaceInterceptor::getLayerId(const sp<const Layer>& layer) const {
@@ -203,12 +200,11 @@
return strongLayer == nullptr ? -1 : getLayerId(strongLayer);
}
-int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<const IBinder>& handle) const {
+int32_t SurfaceInterceptor::getLayerIdFromHandle(const sp<IBinder>& handle) const {
if (handle == nullptr) {
return -1;
}
- const auto layerHandle(static_cast<const Layer::Handle*>(handle.get()));
- const sp<const Layer> layer(layerHandle->owner.promote());
+ const sp<const Layer> layer = Layer::fromHandle(handle).promote();
return layer == nullptr ? -1 : getLayerId(layer);
}
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 673f9e7..c955596 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -133,10 +133,10 @@
void addInitialDisplayStateLocked(Increment* increment, const DisplayDeviceState& display);
status_t writeProtoFileLocked();
- const sp<const Layer> getLayer(const wp<const IBinder>& weakHandle) const;
+ const sp<const Layer> getLayer(const wp<IBinder>& weakHandle) const;
int32_t getLayerId(const sp<const Layer>& layer) const;
int32_t getLayerIdFromWeakRef(const wp<const Layer>& layer) const;
- int32_t getLayerIdFromHandle(const sp<const IBinder>& weakHandle) const;
+ int32_t getLayerIdFromHandle(const sp<IBinder>& weakHandle) const;
Increment* createTraceIncrementLocked();
void addSurfaceCreationLocked(Increment* increment, const sp<const Layer>& layer);
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 3423bd5..3b2bd81 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -2123,7 +2123,11 @@
refreshRateConfigs->setCurrentModeId(HWC_CONFIG_ID_90);
displayRefreshRate = refreshRateConfigs->getCurrentRefreshRate().getFps();
EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.5f)));
- EXPECT_EQ(4, RefreshRateConfigs::getFrameRateDivider(displayRefreshRate, Fps(22.6f)));
+
+ EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(24.f), Fps(25.f)));
+ EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(24.f), Fps(23.976f)));
+ EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(30.f), Fps(29.97f)));
+ EXPECT_EQ(0, RefreshRateConfigs::getFrameRateDivider(Fps(60.f), Fps(59.94f)));
}
TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 2715587..3ed3eba 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1231,6 +1231,12 @@
return VK_ERROR_SURFACE_LOST_KHR;
}
+ // In shared mode the num_images must be one regardless of how many
+ // buffers were allocated for the buffer queue.
+ if (swapchain_image_usage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID) {
+ num_images = 1;
+ }
+
int32_t legacy_usage = 0;
if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
uint64_t consumer_usage, producer_usage;