diff options
Diffstat (limited to 'libs/hwui/renderthread')
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 12 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 6 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 18 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 9 | ||||
-rw-r--r-- | libs/hwui/renderthread/EglManager.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderEffectCapabilityQuery.cpp | 39 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderEffectCapabilityQuery.h | 35 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 3 |
9 files changed, 115 insertions, 20 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 2f3a509831d1..a066e6f7c693 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -491,10 +491,10 @@ nsecs_t CanvasContext::draw() { // Notify the callbacks, even if there's nothing to draw so they aren't waiting // indefinitely waitOnFences(); - for (auto& func : mFrameCompleteCallbacks) { - std::invoke(func, mFrameNumber); + for (auto& func : mFrameCommitCallbacks) { + std::invoke(func, false /* didProduceBuffer */); } - mFrameCompleteCallbacks.clear(); + mFrameCommitCallbacks.clear(); return 0; } @@ -603,10 +603,10 @@ nsecs_t CanvasContext::draw() { #endif if (didSwap) { - for (auto& func : mFrameCompleteCallbacks) { - std::invoke(func, frameCompleteNr); + for (auto& func : mFrameCommitCallbacks) { + std::invoke(func, true /* didProduceBuffer */); } - mFrameCompleteCallbacks.clear(); + mFrameCommitCallbacks.clear(); } if (requireSwap) { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 6dbfcc349d50..9df429badd5e 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -187,8 +187,8 @@ public: IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); } - void addFrameCompleteListener(std::function<void(int64_t)>&& func) { - mFrameCompleteCallbacks.push_back(std::move(func)); + void addFrameCommitListener(std::function<void(bool)>&& func) { + mFrameCommitCallbacks.push_back(std::move(func)); } void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback) { @@ -320,7 +320,7 @@ private: std::vector<std::future<void>> mFrameFences; std::unique_ptr<IRenderPipeline> mRenderPipeline; - std::vector<std::function<void(int64_t)>> mFrameCompleteCallbacks; + std::vector<std::function<void(bool)>> mFrameCommitCallbacks; // If set to true, we expect that callbacks into onSurfaceStatsAvailable bool mExpectSurfaceStats = false; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index e7081df2b558..94aedd0f43be 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -150,16 +150,18 @@ void DrawFrameTask::run() { canUnblockUiThread = syncFrameState(info); canDrawThisFrame = info.out.canDrawThisFrame; - if (mFrameCompleteCallback) { - mContext->addFrameCompleteListener(std::move(mFrameCompleteCallback)); - mFrameCompleteCallback = nullptr; + if (mFrameCommitCallback) { + mContext->addFrameCommitListener(std::move(mFrameCommitCallback)); + mFrameCommitCallback = nullptr; } } // Grab a copy of everything we need CanvasContext* context = mContext; - std::function<void(int64_t)> callback = std::move(mFrameCallback); + std::function<void(int64_t)> frameCallback = std::move(mFrameCallback); + std::function<void()> frameCompleteCallback = std::move(mFrameCompleteCallback); mFrameCallback = nullptr; + mFrameCompleteCallback = nullptr; int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)]; int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)]; int64_t frameStartTime = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameStartTime)]; @@ -170,9 +172,9 @@ void DrawFrameTask::run() { } // Even if we aren't drawing this vsync pulse the next frame number will still be accurate - if (CC_UNLIKELY(callback)) { + if (CC_UNLIKELY(frameCallback)) { context->enqueueFrameWork( - [callback, frameNr = context->getFrameNumber()]() { callback(frameNr); }); + [frameCallback, frameNr = context->getFrameNumber()]() { frameCallback(frameNr); }); } nsecs_t dequeueBufferDuration = 0; @@ -189,6 +191,10 @@ void DrawFrameTask::run() { context->waitOnFences(); } + if (CC_UNLIKELY(frameCompleteCallback)) { + std::invoke(frameCompleteCallback); + } + if (!canUnblockUiThread) { unblockUiThread(); } diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index 6a61a2bb645f..e3ea802b07b9 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -81,7 +81,11 @@ public: mFrameCallback = std::move(callback); } - void setFrameCompleteCallback(std::function<void(int64_t)>&& callback) { + void setFrameCommitCallback(std::function<void(bool)>&& callback) { + mFrameCommitCallback = std::move(callback); + } + + void setFrameCompleteCallback(std::function<void()>&& callback) { mFrameCompleteCallback = std::move(callback); } @@ -123,7 +127,8 @@ private: int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; std::function<void(int64_t)> mFrameCallback; - std::function<void(int64_t)> mFrameCompleteCallback; + std::function<void(bool)> mFrameCommitCallback; + std::function<void()> mFrameCompleteCallback; nsecs_t mLastDequeueBufferDuration = 0; nsecs_t mLastTargetWorkDuration = 0; diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 383c79b27918..c7d7a17a23eb 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -28,6 +28,7 @@ #include "Frame.h" #include "Properties.h" +#include "RenderEffectCapabilityQuery.h" #include "utils/Color.h" #include "utils/StringUtils.h" @@ -148,7 +149,11 @@ void EglManager::initialize() { mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension; auto* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); - Properties::enableRenderEffectCache = (strcmp(vendor, "Qualcomm") != 0); + auto* version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); + Properties::enableRenderEffectCache = supportsRenderEffectCache( + vendor, version); + ALOGV("RenderEffectCache supported %d on driver version %s", + Properties::enableRenderEffectCache, version); } EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavior swapBehavior) { diff --git a/libs/hwui/renderthread/RenderEffectCapabilityQuery.cpp b/libs/hwui/renderthread/RenderEffectCapabilityQuery.cpp new file mode 100644 index 000000000000..a003988575c8 --- /dev/null +++ b/libs/hwui/renderthread/RenderEffectCapabilityQuery.cpp @@ -0,0 +1,39 @@ +/* + * 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 <stdio.h> +#include <string.h> +#include <utils/Log.h> + +bool supportsRenderEffectCache(const char* vendor, const char* version) { + if (strcmp(vendor, "Qualcomm") != 0) { + return true; + } + + int major; + int minor; + int driverMajor; + int driverMinor; + int n = sscanf(version,"OpenGL ES %d.%d V@%d.%d", + &major, + &minor, + &driverMajor, + &driverMinor); + // Ensure we have parsed the vendor string properly and we have either + // a newer major driver version, or the minor version is rev'ed + // Based on b/198227600#comment5 it appears that the corresponding fix + // is in driver version 571.0 + return n == 4 && driverMajor >= 571; +}
\ No newline at end of file diff --git a/libs/hwui/renderthread/RenderEffectCapabilityQuery.h b/libs/hwui/renderthread/RenderEffectCapabilityQuery.h new file mode 100644 index 000000000000..ea673dd0386d --- /dev/null +++ b/libs/hwui/renderthread/RenderEffectCapabilityQuery.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#pragma once + +/** + * Verify if the provided vendor and version supports RenderEffect caching + * behavior. + * + * Certain Open GL Driver implementations run into blocking scenarios + * with Fence::waitForever without a corresponding signal to unblock + * This happens during attempts to cache SkImage instances across frames + * especially in circumstances using RenderEffect/SkImageFilter internally. + * So detect the corresponding GL Vendor and driver version to determine if + * caching SkImage instances across frames is supported. + * See b/197263715 & b/193145089 + * @param vendor Vendor of the GL driver + * @param version Version of the GL driver from the given vendor + * @return True if a RenderEffect result can be cached across frames, + * false otherwise + */ +bool supportsRenderEffectCache(const char* vendor, const char* version); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index c485ce2781e5..72d4ac5081e6 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -326,7 +326,11 @@ void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) { mDrawFrameTask.setFrameCallback(std::move(callback)); } -void RenderProxy::setFrameCompleteCallback(std::function<void(int64_t)>&& callback) { +void RenderProxy::setFrameCommitCallback(std::function<void(bool)>&& callback) { + mDrawFrameTask.setFrameCommitCallback(std::move(callback)); +} + +void RenderProxy::setFrameCompleteCallback(std::function<void()>&& callback) { mDrawFrameTask.setFrameCompleteCallback(std::move(callback)); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 2b5405c82563..6417b38df064 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -124,7 +124,8 @@ public: const std::function<bool(int64_t, int64_t, int64_t)>& callback); void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback); void setFrameCallback(std::function<void(int64_t)>&& callback); - void setFrameCompleteCallback(std::function<void(int64_t)>&& callback); + void setFrameCommitCallback(std::function<void(bool)>&& callback); + void setFrameCompleteCallback(std::function<void()>&& callback); void addFrameMetricsObserver(FrameMetricsObserver* observer); void removeFrameMetricsObserver(FrameMetricsObserver* observer); |