summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/RenderThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/renderthread/RenderThread.cpp')
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp153
1 files changed, 117 insertions, 36 deletions
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 206b58f62ea7..4ba774801bba 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,10 +16,12 @@
#include "RenderThread.h"
+#include <gui/TraceUtils.h>
#include "../HardwareBitmapUploader.h"
#include "CanvasContext.h"
#include "DeviceInfo.h"
#include "EglManager.h"
+#include "Properties.h"
#include "Readback.h"
#include "RenderProxy.h"
#include "VulkanManager.h"
@@ -28,17 +30,18 @@
#include "pipeline/skia/SkiaVulkanPipeline.h"
#include "renderstate/RenderState.h"
#include "utils/TimeUtils.h"
-#include "utils/TraceUtils.h"
#include <GrContextOptions.h>
#include <gl/GrGLInterface.h>
+#include <dlfcn.h>
#include <sys/resource.h>
#include <utils/Condition.h>
#include <utils/Log.h>
#include <utils/Mutex.h>
#include <thread>
+#include <android-base/properties.h>
#include <ui/FatVector.h>
namespace android {
@@ -49,10 +52,66 @@ static bool gHasRenderThreadInstance = false;
static JVMAttachHook gOnStartHook = nullptr;
+ASurfaceControlFunctions::ASurfaceControlFunctions() {
+ void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
+ createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
+ LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_create!");
+
+ acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
+ LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_acquire!");
+
+ releaseFunc = (ASC_release) dlsym(handle_, "ASurfaceControl_release");
+ LOG_ALWAYS_FATAL_IF(releaseFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_release!");
+
+ registerListenerFunc = (ASC_registerSurfaceStatsListener) dlsym(handle_,
+ "ASurfaceControl_registerSurfaceStatsListener");
+ LOG_ALWAYS_FATAL_IF(registerListenerFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_registerSurfaceStatsListener!");
+
+ unregisterListenerFunc = (ASC_unregisterSurfaceStatsListener) dlsym(handle_,
+ "ASurfaceControl_unregisterSurfaceStatsListener");
+ LOG_ALWAYS_FATAL_IF(unregisterListenerFunc == nullptr,
+ "Failed to find required symbol ASurfaceControl_unregisterSurfaceStatsListener!");
+
+ getAcquireTimeFunc = (ASCStats_getAcquireTime) dlsym(handle_,
+ "ASurfaceControlStats_getAcquireTime");
+ LOG_ALWAYS_FATAL_IF(getAcquireTimeFunc == nullptr,
+ "Failed to find required symbol ASurfaceControlStats_getAcquireTime!");
+
+ getFrameNumberFunc = (ASCStats_getFrameNumber) dlsym(handle_,
+ "ASurfaceControlStats_getFrameNumber");
+ LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
+ "Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
+
+ transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
+ LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_create!");
+
+ transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
+ LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_delete!");
+
+ transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
+ LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_apply!");
+
+ transactionSetVisibilityFunc =
+ (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
+ LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
+ "Failed to find required symbol ASurfaceTransaction_setVisibility!");
+}
+
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
RenderThread* rt = reinterpret_cast<RenderThread*>(data);
+ int64_t vsyncId = AChoreographer_getVsyncId(rt->mChoreographer);
+ int64_t frameDeadline = AChoreographer_getFrameDeadline(rt->mChoreographer);
+ int64_t frameInterval = AChoreographer_getFrameInterval(rt->mChoreographer);
rt->mVsyncRequested = false;
- if (rt->timeLord().vsyncReceived(frameTimeNanos) && !rt->mFrameCallbackTaskPending) {
+ if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId, frameDeadline,
+ frameInterval) && !rt->mFrameCallbackTaskPending) {
ATRACE_NAME("queue mFrameCallbackTask");
rt->mFrameCallbackTaskPending = true;
nsecs_t runAt = (frameTimeNanos + rt->mDispatchFrameDelay);
@@ -116,10 +175,11 @@ JVMAttachHook RenderThread::getOnStartHook() {
}
RenderThread& RenderThread::getInstance() {
- // This is a pointer because otherwise __cxa_finalize
- // will try to delete it like a Good Citizen but that causes us to crash
- // because we don't want to delete the RenderThread normally.
- static RenderThread* sInstance = new RenderThread();
+ [[clang::no_destroy]] static sp<RenderThread> sInstance = []() {
+ sp<RenderThread> thread = sp<RenderThread>::make();
+ thread->start("RenderThread");
+ return thread;
+ }();
gHasRenderThreadInstance = true;
return *sInstance;
}
@@ -132,9 +192,8 @@ RenderThread::RenderThread()
, mRenderState(nullptr)
, mEglManager(nullptr)
, mFunctorManager(WebViewFunctorManager::instance())
- , mVkManager(nullptr) {
+ , mGlobalProfileData(mJankDataMutex) {
Properties::load();
- start("RenderThread");
}
RenderThread::~RenderThread() {
@@ -166,7 +225,7 @@ void RenderThread::initThreadLocals() {
initializeChoreographer();
mEglManager = new EglManager();
mRenderState = new RenderState(*this);
- mVkManager = new VulkanManager();
+ mVkManager = VulkanManager::getInstance();
mCacheManager = new CacheManager();
}
@@ -190,13 +249,17 @@ void RenderThread::requireGlContext() {
auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
auto size = glesVersion ? strlen(glesVersion) : -1;
cacheManager().configureContext(&options, glesVersion, size);
- sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
+ sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options));
LOG_ALWAYS_FATAL_IF(!grContext.get());
setGrContext(grContext);
}
void RenderThread::requireVkContext() {
- if (mVkManager->hasVkContext()) {
+ // the getter creates the context in the event it had been destroyed by destroyRenderingContext
+ // Also check if we have a GrContext before returning fast. VulkanManager may be shared with
+ // the HardwareBitmapUploader which initializes the Vk context without persisting the GrContext
+ // in the rendering thread.
+ if (vulkanManager().hasVkContext() && mGrContext) {
return;
}
mVkManager->initialize();
@@ -204,7 +267,7 @@ void RenderThread::requireVkContext() {
initGrContextOptions(options);
auto vkDriverVersion = mVkManager->getDriverVersion();
cacheManager().configureContext(&options, &vkDriverVersion, sizeof(vkDriverVersion));
- sk_sp<GrContext> grContext = mVkManager->createContext(options);
+ sk_sp<GrDirectContext> grContext = mVkManager->createContext(options);
LOG_ALWAYS_FATAL_IF(!grContext.get());
setGrContext(grContext);
}
@@ -212,6 +275,11 @@ void RenderThread::requireVkContext() {
void RenderThread::initGrContextOptions(GrContextOptions& options) {
options.fPreferExternalImagesOverES3 = true;
options.fDisableDistanceFieldPaths = true;
+ if (android::base::GetBoolProperty(PROPERTY_REDUCE_OPS_TASK_SPLITTING, true)) {
+ options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kYes;
+ } else {
+ options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
+ }
}
void RenderThread::destroyRenderingContext() {
@@ -222,37 +290,41 @@ void RenderThread::destroyRenderingContext() {
mEglManager->destroy();
}
} else {
- if (vulkanManager().hasVkContext()) {
- setGrContext(nullptr);
- vulkanManager().destroy();
- }
+ setGrContext(nullptr);
+ mVkManager.clear();
}
}
-void RenderThread::dumpGraphicsMemory(int fd) {
- globalProfileData()->dump(fd);
+VulkanManager& RenderThread::vulkanManager() {
+ if (!mVkManager.get()) {
+ mVkManager = VulkanManager::getInstance();
+ }
+ return *mVkManager.get();
+}
- String8 cachesOutput;
- String8 pipeline;
- auto renderType = Properties::getRenderPipelineType();
- switch (renderType) {
- case RenderPipelineType::SkiaGL: {
- mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
- pipeline.appendFormat("Skia (OpenGL)");
- break;
- }
- case RenderPipelineType::SkiaVulkan: {
- mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
- pipeline.appendFormat("Skia (Vulkan)");
- break;
- }
+static const char* pipelineToString() {
+ switch (auto renderType = Properties::getRenderPipelineType()) {
+ case RenderPipelineType::SkiaGL:
+ return "Skia (OpenGL)";
+ case RenderPipelineType::SkiaVulkan:
+ return "Skia (Vulkan)";
default:
LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);
- break;
}
+}
+
+void RenderThread::dumpGraphicsMemory(int fd, bool includeProfileData) {
+ if (includeProfileData) {
+ globalProfileData()->dump(fd);
+ }
+
+ String8 cachesOutput;
+ mCacheManager->dumpMemoryUsage(cachesOutput, mRenderState);
+ dprintf(fd, "\nPipeline=%s\n%s\n", pipelineToString(), cachesOutput.string());
+}
- dprintf(fd, "\n%s\n", cachesOutput.string());
- dprintf(fd, "\nPipeline=%s\n", pipeline.string());
+void RenderThread::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) {
+ mCacheManager->getMemoryUsage(cpuUsage, gpuUsage);
}
Readback& RenderThread::readback() {
@@ -263,7 +335,7 @@ Readback& RenderThread::readback() {
return *mReadback;
}
-void RenderThread::setGrContext(sk_sp<GrContext> context) {
+void RenderThread::setGrContext(sk_sp<GrDirectContext> context) {
mCacheManager->reset(context);
if (mGrContext) {
mRenderState->onContextDestroyed();
@@ -275,6 +347,15 @@ void RenderThread::setGrContext(sk_sp<GrContext> context) {
}
}
+sk_sp<GrDirectContext> RenderThread::requireGrContext() {
+ if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+ requireGlContext();
+ } else {
+ requireVkContext();
+ }
+ return mGrContext;
+}
+
int RenderThread::choreographerCallback(int fd, int events, void* data) {
if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
ALOGE("Display event receiver pipe was closed or an error occurred. "