summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2018-03-16 17:27:17 -0700
committer John Reck <jreck@google.com> 2018-03-16 17:34:02 -0700
commit564284759f014c141cb8b8403b036833f50f49ef (patch)
tree3bef3a4db7c34d3b62d54f746c5da6854b2c35a0
parent3912a7f54466f258c5b2597eebdb54cfe0f8281c (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.java3
-rw-r--r--core/java/android/view/ThreadedRenderer.java21
-rw-r--r--core/jni/android_view_ThreadedRenderer.cpp6
-rw-r--r--libs/hwui/DeviceInfo.cpp29
-rw-r--r--libs/hwui/DeviceInfo.h3
-rw-r--r--libs/hwui/Properties.cpp1
-rw-r--r--libs/hwui/Properties.h1
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp113
-rw-r--r--libs/hwui/renderthread/RenderThread.h12
-rw-r--r--libs/hwui/tests/unit/main.cpp2
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);