diff options
author | 2018-03-16 17:27:17 -0700 | |
---|---|---|
committer | 2018-03-16 17:34:02 -0700 | |
commit | 564284759f014c141cb8b8403b036833f50f49ef (patch) | |
tree | 3bef3a4db7c34d3b62d54f746c5da6854b2c35a0 | |
parent | 3912a7f54466f258c5b2597eebdb54cfe0f8281c (diff) |
Don't use IPC in isolateProcess
Fixes: 74395652
Test: hwuiunit passes in 'shell stop' state (pseudo-isolated process),
manually checked non-isolated processes still have working vsync
via systrace of RT animations demo
Change-Id: I630ea011dc7eb2efa265b25673d3304b3b2510d3
-rw-r--r-- | core/java/android/app/ActivityThread.java | 3 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 21 | ||||
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/DeviceInfo.cpp | 29 | ||||
-rw-r--r-- | libs/hwui/DeviceInfo.h | 3 | ||||
-rw-r--r-- | libs/hwui/Properties.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 1 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 113 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 12 | ||||
-rw-r--r-- | libs/hwui/tests/unit/main.cpp | 2 |
10 files changed, 139 insertions, 52 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 8dd0f428648e..99bcdb9fe1d9 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5652,6 +5652,7 @@ public final class ActivityThread extends ClientTransactionHandler { // Allow application-generated systrace messages if we're debuggable. boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; Trace.setAppTracingAllowed(isAppDebuggable); + ThreadedRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE); if (isAppDebuggable && data.enableBinderTracking) { Binder.enableTracing(); } @@ -5710,6 +5711,8 @@ public final class ActivityThread extends ClientTransactionHandler { } finally { StrictMode.setThreadPolicyMask(oldMask); } + } else { + ThreadedRenderer.setIsolatedProcess(true); } // If we use profiles, setup the dex reporter to notify package manager diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 8d076f75ddbb..5eb7e9cb2efe 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -20,13 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; -import android.content.pm.ApplicationInfo; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.AnimatedVectorDrawable; -import android.os.Build; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -936,6 +934,20 @@ public final class ThreadedRenderer { nSetHighContrastText(highContrastText); } + /** + * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source + */ + public static void setIsolatedProcess(boolean isIsolated) { + nSetIsolatedProcess(isIsolated); + } + + /** + * If set extra graphics debugging abilities will be enabled such as dumping skp + */ + public static void setDebuggingEnabled(boolean enable) { + nSetDebuggingEnabled(enable); + } + @Override protected void finalize() throws Throwable { try { @@ -1071,10 +1083,6 @@ public final class ThreadedRenderer { initSched(renderProxy); if (mAppContext != null) { - final boolean appDebuggable = - (mAppContext.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) - != 0; - nSetDebuggingEnabled(appDebuggable || Build.IS_DEBUGGABLE); initGraphicsStats(); } } @@ -1204,4 +1212,5 @@ public final class ThreadedRenderer { // For temporary experimentation b/66945974 private static native void nHackySetRTAnimationsEnabled(boolean enabled); private static native void nSetDebuggingEnabled(boolean enabled); + private static native void nSetIsolatedProcess(boolean enabled); } diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index b614c891b9f8..451f278313b5 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -988,6 +988,11 @@ static void android_view_ThreadedRenderer_setDebuggingEnabled(JNIEnv*, jclass, j Properties::debuggingEnabled = enable; } +static void android_view_ThreadedRenderer_setIsolatedProcess(JNIEnv*, jclass, jboolean isolated) { + Properties::isolatedProcess = isolated; +} + + // ---------------------------------------------------------------------------- // FrameMetricsObserver // ---------------------------------------------------------------------------- @@ -1097,6 +1102,7 @@ static const JNINativeMethod gMethods[] = { { "nHackySetRTAnimationsEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled }, { "nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled }, + { "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess }, }; static JavaVM* mJvm = nullptr; diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp index e4162875279c..40cc73a82846 100644 --- a/libs/hwui/DeviceInfo.cpp +++ b/libs/hwui/DeviceInfo.cpp @@ -16,6 +16,8 @@ #include <DeviceInfo.h> +#include "Properties.h" + #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> @@ -29,6 +31,19 @@ namespace android { namespace uirenderer { +static constexpr android::DisplayInfo sDummyDisplay { + 1080, // w + 1920, // h + 320.0, // xdpi + 320.0, // ydpi + 60.0, // fps + 2.0, // density + 0, // orientation + false, // secure? + 0, // appVsyncOffset + 0, // presentationDeadline +}; + static DeviceInfo* sDeviceInfo = nullptr; static std::once_flag sInitializedFlag; @@ -47,20 +62,26 @@ void DeviceInfo::initialize() { void DeviceInfo::initialize(int maxTextureSize) { std::call_once(sInitializedFlag, [maxTextureSize]() { sDeviceInfo = new DeviceInfo(); - sDeviceInfo->loadDisplayInfo(); + sDeviceInfo->mDisplayInfo = DeviceInfo::queryDisplayInfo(); sDeviceInfo->mMaxTextureSize = maxTextureSize; }); } void DeviceInfo::load() { - loadDisplayInfo(); + mDisplayInfo = queryDisplayInfo(); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); } -void DeviceInfo::loadDisplayInfo() { +DisplayInfo DeviceInfo::queryDisplayInfo() { + if (Properties::isolatedProcess) { + return sDummyDisplay; + } + + DisplayInfo displayInfo; sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); - status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &mDisplayInfo); + status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &displayInfo); LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status); + return displayInfo; } } /* namespace uirenderer */ diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h index a0b2f06d8f4a..297b2664414b 100644 --- a/libs/hwui/DeviceInfo.h +++ b/libs/hwui/DeviceInfo.h @@ -47,12 +47,13 @@ public: return di.w * di.h * in; } + static DisplayInfo queryDisplayInfo(); + private: DeviceInfo() {} ~DeviceInfo() {} void load(); - void loadDisplayInfo(); int mMaxTextureSize; DisplayInfo mDisplayInfo; diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index e9adbdc1447b..1602b4b39c91 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -63,6 +63,7 @@ bool Properties::enableRTAnimations = true; bool Properties::runningInEmulator = false; bool Properties::debuggingEnabled = false; +bool Properties::isolatedProcess = false; static int property_get_int(const char* key, int defaultValue) { char buf[PROPERTY_VALUE_MAX] = { diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 3f44c211f024..81a36574a097 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -269,6 +269,7 @@ public: static bool runningInEmulator; ANDROID_API static bool debuggingEnabled; + ANDROID_API static bool isolatedProcess; private: static ProfileType sProfileType; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 8e0546b529af..6a2a025da121 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -17,6 +17,7 @@ #include "RenderThread.h" #include "CanvasContext.h" +#include "DeviceInfo.h" #include "EglManager.h" #include "OpenGLReadback.h" #include "RenderProxy.h" @@ -29,10 +30,9 @@ #include "renderstate/RenderState.h" #include "renderthread/OpenGLPipeline.h" #include "utils/FatVector.h" +#include "utils/TimeUtils.h" #include <gui/DisplayEventReceiver.h> -#include <gui/ISurfaceComposer.h> -#include <gui/SurfaceComposerClient.h> #include <sys/resource.h> #include <utils/Condition.h> #include <utils/Log.h> @@ -54,6 +54,58 @@ static bool gHasRenderThreadInstance = false; static void (*gOnStartHook)() = nullptr; +class DisplayEventReceiverWrapper : public VsyncSource { +public: + DisplayEventReceiverWrapper(std::unique_ptr<DisplayEventReceiver>&& receiver) + : mDisplayEventReceiver(std::move(receiver)) {} + + virtual void requestNextVsync() override { + status_t status = mDisplayEventReceiver->requestNextVsync(); + LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "requestNextVsync failed with status: %d", status); + } + + virtual nsecs_t latestVsyncEvent() override { + DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; + nsecs_t latest = 0; + ssize_t n; + while ((n = mDisplayEventReceiver->getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { + for (ssize_t i = 0; i < n; i++) { + const DisplayEventReceiver::Event& ev = buf[i]; + switch (ev.header.type) { + case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: + latest = ev.header.timestamp; + break; + } + } + } + if (n < 0) { + ALOGW("Failed to get events from display event receiver, status=%d", status_t(n)); + } + return latest; + } + +private: + std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver; +}; + +class DummyVsyncSource : public VsyncSource { +public: + DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {} + + virtual void requestNextVsync() override { + mRenderThread->queue().postDelayed(16_ms, [this]() { + mRenderThread->drainDisplayEventQueue(); + }); + } + + virtual nsecs_t latestVsyncEvent() override { + return systemTime(CLOCK_MONOTONIC); + } + +private: + RenderThread* mRenderThread; +}; + bool RenderThread::hasInstance() { return gHasRenderThreadInstance; } @@ -74,7 +126,7 @@ RenderThread& RenderThread::getInstance() { RenderThread::RenderThread() : ThreadBase() - , mDisplayEventReceiver(nullptr) + , mVsyncSource(nullptr) , mVsyncRequested(false) , mFrameCallbackTaskPending(false) , mRenderState(nullptr) @@ -89,23 +141,27 @@ RenderThread::~RenderThread() { } void RenderThread::initializeDisplayEventReceiver() { - LOG_ALWAYS_FATAL_IF(mDisplayEventReceiver, "Initializing a second DisplayEventReceiver?"); - mDisplayEventReceiver = new DisplayEventReceiver(); - status_t status = mDisplayEventReceiver->initCheck(); - LOG_ALWAYS_FATAL_IF(status != NO_ERROR, - "Initialization of DisplayEventReceiver " - "failed with status: %d", - status); + LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second DisplayEventReceiver?"); - // Register the FD - mLooper->addFd(mDisplayEventReceiver->getFd(), 0, Looper::EVENT_INPUT, - RenderThread::displayEventReceiverCallback, this); + if (!Properties::isolatedProcess) { + auto receiver = std::make_unique<DisplayEventReceiver>(); + status_t status = receiver->initCheck(); + LOG_ALWAYS_FATAL_IF(status != NO_ERROR, + "Initialization of DisplayEventReceiver " + "failed with status: %d", + status); + + // Register the FD + mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT, + RenderThread::displayEventReceiverCallback, this); + mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver)); + } else { + mVsyncSource = new DummyVsyncSource(this); + } } void RenderThread::initThreadLocals() { - sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); - status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &mDisplayInfo); - LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n"); + mDisplayInfo = DeviceInfo::queryDisplayInfo(); nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / mDisplayInfo.fps); mTimeLord.setFrameInterval(frameIntervalNanos); initializeDisplayEventReceiver(); @@ -201,29 +257,9 @@ int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { return 1; // keep the callback } -static nsecs_t latestVsyncEvent(DisplayEventReceiver* receiver) { - DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; - nsecs_t latest = 0; - ssize_t n; - while ((n = receiver->getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { - for (ssize_t i = 0; i < n; i++) { - const DisplayEventReceiver::Event& ev = buf[i]; - switch (ev.header.type) { - case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: - latest = ev.header.timestamp; - break; - } - } - } - if (n < 0) { - ALOGW("Failed to get events from display event receiver, status=%d", status_t(n)); - } - return latest; -} - void RenderThread::drainDisplayEventQueue() { ATRACE_CALL(); - nsecs_t vsyncEvent = latestVsyncEvent(mDisplayEventReceiver); + nsecs_t vsyncEvent = mVsyncSource->latestVsyncEvent(); if (vsyncEvent > 0) { mVsyncRequested = false; if (mTimeLord.vsyncReceived(vsyncEvent) && !mFrameCallbackTaskPending) { @@ -256,8 +292,7 @@ void RenderThread::dispatchFrameCallbacks() { void RenderThread::requestVsync() { if (!mVsyncRequested) { mVsyncRequested = true; - status_t status = mDisplayEventReceiver->requestNextVsync(); - LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "requestNextVsync failed with status: %d", status); + mVsyncSource->requestNextVsync(); } } diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 3aa548773b3b..689f518bad1b 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -39,7 +39,6 @@ namespace android { class Bitmap; -class DisplayEventReceiver; namespace uirenderer { @@ -63,6 +62,14 @@ protected: ~IFrameCallback() {} }; +struct VsyncSource { + virtual void requestNextVsync() = 0; + virtual nsecs_t latestVsyncEvent() = 0; + virtual ~VsyncSource() {} +}; + +class DummyVsyncSource; + class RenderThread : private ThreadBase { PREVENT_COPY_AND_ASSIGN(RenderThread); @@ -110,6 +117,7 @@ protected: private: friend class DispatchFrameCallbacks; friend class RenderProxy; + friend class DummyVsyncSource; friend class android::uirenderer::TestUtils; RenderThread(); @@ -127,7 +135,7 @@ private: DisplayInfo mDisplayInfo; - DisplayEventReceiver* mDisplayEventReceiver; + VsyncSource* mVsyncSource; bool mVsyncRequested; std::set<IFrameCallback*> mFrameCallbacks; // We defer the actual registration of these callbacks until diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp index 406255d61d25..9e6d9a8c27de 100644 --- a/libs/hwui/tests/unit/main.cpp +++ b/libs/hwui/tests/unit/main.cpp @@ -21,6 +21,7 @@ #include "debug/GlesDriver.h" #include "debug/NullGlesDriver.h" #include "hwui/Typeface.h" +#include "Properties.h" #include "tests/common/LeakChecker.h" #include "thread/TaskManager.h" @@ -67,6 +68,7 @@ int main(int argc, char* argv[]) { // Replace the default GLES driver debug::GlesDriver::replace(std::make_unique<debug::NullGlesDriver>()); + Properties::isolatedProcess = true; // Run the tests testing::InitGoogleTest(&argc, argv); |