Merge "Revert "fix drawWithOpengl""
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 3d63971..c7b51c8 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -116,7 +116,8 @@
{ "database", "Database", ATRACE_TAG_DATABASE, { } },
{ "network", "Network", ATRACE_TAG_NETWORK, { } },
{ "adb", "ADB", ATRACE_TAG_ADB, { } },
- { "vibrator", "Vibrator", ATRACE_TAG_VIBRATOR, {}},
+ { "vibrator", "Vibrator", ATRACE_TAG_VIBRATOR, { } },
+ { "aidl", "AIDL calls", ATRACE_TAG_AIDL, { } },
{ k_coreServiceCategory, "Core services", 0, { } },
{ k_pdxServiceCategory, "PDX services", 0, { } },
{ "sched", "CPU Scheduling", 0, {
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index fd2fccb..9648ede 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1159,6 +1159,10 @@
static void RunDumpsysProto(const std::string& title, int priority,
std::chrono::milliseconds timeout,
std::chrono::milliseconds service_timeout) {
+ if (!ds.IsZipping()) {
+ MYLOGD("Not dumping %s because it's not a zipped bugreport\n", title.c_str());
+ return;
+ }
sp<android::IServiceManager> sm = defaultServiceManager();
Dumpsys dumpsys(sm.get());
Vector<String16> args;
@@ -1630,20 +1634,8 @@
ShowUsageAndExit();
}
-static void sig_handler(int) {
- _exit(EXIT_FAILURE);
-}
-
static void register_sig_handler() {
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sig_handler;
- sigaction(SIGPIPE, &sa, NULL); // broken pipe
- sigaction(SIGSEGV, &sa, NULL); // segment fault
- sigaction(SIGINT, &sa, NULL); // ctrl-c
- sigaction(SIGTERM, &sa, NULL); // killed
- sigaction(SIGQUIT, &sa, NULL); // quit
+ signal(SIGPIPE, SIG_IGN);
}
bool Dumpstate::FinishZipFile() {
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 3dfb7e0..29ef648 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -378,8 +378,7 @@
}
if (findAndBumpVersion(hal, version)) {
if (&table != &mImplementationsTable) {
- hal->interfaces[interfaceName].name = interfaceName;
- hal->interfaces[interfaceName].instances.insert(instanceName);
+ hal->insertLegacyInstance(interfaceName, instanceName);
}
hal->transportArch.arch |= arch;
done = true;
@@ -389,17 +388,16 @@
if (done) {
continue; // to next TableEntry
}
- decltype(vintf::ManifestHal::interfaces) interfaces;
- if (&table != &mImplementationsTable) {
- interfaces[interfaceName].name = interfaceName;
- interfaces[interfaceName].instances.insert(instanceName);
- }
- if (!manifest.add(vintf::ManifestHal{
+ vintf::ManifestHal manifestHal{
vintf::HalFormat::HIDL,
std::string{fqName.package()},
{version},
{transport, arch},
- std::move(interfaces)})) {
+ {}};
+ if (&table != &mImplementationsTable) {
+ manifestHal.insertLegacyInstance(interfaceName, instanceName);
+ }
+ if (!manifest.add(std::move(manifestHal))) {
err() << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
}
}
@@ -408,7 +406,7 @@
<< " This is a skeleton " << manifest.type() << " manifest. Notes: " << std::endl
<< INIT_VINTF_NOTES
<< "-->" << std::endl;
- out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_ONLY);
+ out << vintf::gHalManifestConverter(manifest, vintf::SerializeFlag::HALS_NO_FQNAME);
}
std::string ListCommand::INIT_VINTF_NOTES{
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 679f44b..a6890ee 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -47,8 +47,8 @@
~BpSurfaceComposerClient() override;
status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,
- uint32_t flags, const sp<IBinder>& parent, uint32_t windowType,
- uint32_t ownerUid, sp<IBinder>* handle,
+ uint32_t flags, const sp<IBinder>& parent, int32_t windowType,
+ int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp) override {
return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,
name, width, height,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 38f0eb7..3cf49d6 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -609,8 +609,8 @@
PixelFormat format,
uint32_t flags,
SurfaceControl* parent,
- uint32_t windowType,
- uint32_t ownerUid)
+ int32_t windowType,
+ int32_t ownerUid)
{
sp<SurfaceControl> s;
createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid);
@@ -625,8 +625,8 @@
sp<SurfaceControl>* outSurface,
uint32_t flags,
SurfaceControl* parent,
- uint32_t windowType,
- uint32_t ownerUid)
+ int32_t windowType,
+ int32_t ownerUid)
{
sp<SurfaceControl> sur;
status_t err = NO_ERROR;
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index d5bbef2..8dfc99a 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -49,8 +49,8 @@
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags, const sp<IBinder>& parent, uint32_t windowType,
- uint32_t ownerUid, sp<IBinder>* handle,
+ uint32_t flags, const sp<IBinder>& parent, int32_t windowType,
+ int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp) = 0;
/*
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 5ce20ad..b45ce4f 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -111,8 +111,8 @@
PixelFormat format, // pixel-format desired
uint32_t flags = 0, // usage flags
SurfaceControl* parent = nullptr, // parent
- uint32_t windowType = 0, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
- uint32_t ownerUid = 0 // UID of the task
+ int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
+ int32_t ownerUid = -1 // UID of the task
);
status_t createSurfaceChecked(
@@ -123,8 +123,8 @@
sp<SurfaceControl>* outSurface,
uint32_t flags = 0, // usage flags
SurfaceControl* parent = nullptr, // parent
- uint32_t windowType = 0, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
- uint32_t ownerUid = 0 // UID of the task
+ int32_t windowType = -1, // from WindowManager.java (STATUS_BAR, INPUT_METHOD, etc.)
+ int32_t ownerUid = -1 // UID of the task
);
//! Create a virtual display
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index b453d19..78f8f0d 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1108,38 +1108,6 @@
egl_tls_t::setContext(EGL_NO_CONTEXT);
}
} else {
-
- if (cur_c != NULL) {
- // Force return to current context for drivers that cannot handle errors
- EGLBoolean restore_result = EGL_FALSE;
- // get a reference to the old current objects
- ContextRef _c2(dp.get(), cur_c);
- SurfaceRef _d2(dp.get(), cur_c->draw);
- SurfaceRef _r2(dp.get(), cur_c->read);
-
- c = cur_c;
- impl_ctx = c->context;
- impl_draw = EGL_NO_SURFACE;
- if (cur_c->draw != EGL_NO_SURFACE) {
- d = get_surface(cur_c->draw);
- impl_draw = d->surface;
- }
- impl_read = EGL_NO_SURFACE;
- if (cur_c->read != EGL_NO_SURFACE) {
- r = get_surface(cur_c->read);
- impl_read = r->surface;
- }
- restore_result = dp->makeCurrent(c, cur_c,
- cur_c->draw, cur_c->read, cur_c->context,
- impl_draw, impl_read, impl_ctx);
- if (restore_result == EGL_TRUE) {
- _c2.acquire();
- _r2.acquire();
- _d2.acquire();
- } else {
- ALOGE("Could not restore original EGL context");
- }
- }
// this will ALOGE the error
egl_connection_t* const cnx = &gEGLImpl;
result = setError(cnx->egl.eglGetError(), (EGLBoolean)EGL_FALSE);
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 916576a..a6caf29 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -593,14 +593,32 @@
const auto& viewport = displayDevice->getViewport();
Region visible = tr.transform(visibleRegion.intersect(viewport));
auto hwcId = displayDevice->getHwcDisplayId();
+ auto& hwcInfo = getBE().mHwcLayers[hwcId];
+ auto& hwcLayer = hwcInfo.layer;
+ auto error = (*hwcLayer)->setVisibleRegion(visible);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ visible.dump(LOG_TAG);
+ }
- getBE().compositionInfo.hwc.visibleRegion = visible;
- getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion;
+ error = (*hwcLayer)->setSurfaceDamage(surfaceDamageRegion);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ surfaceDamageRegion.dump(LOG_TAG);
+ }
// Sideband layers
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
setCompositionType(hwcId, HWC2::Composition::Sideband);
- getBE().compositionInfo.compositionType = HWC2::Composition::Sideband;
+ ALOGV("[%s] Requesting Sideband composition", mName.string());
+ error = (*hwcLayer)->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
+ getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
return;
}
@@ -613,13 +631,32 @@
setCompositionType(hwcId, HWC2::Composition::Device);
}
- getBE().compositionInfo.hwc.dataspace = mDrawingState.dataSpace;
- getBE().compositionInfo.hwc.hdrMetadata = mConsumer->getCurrentHdrMetadata();
+ ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace);
+ error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
+ const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
+ error = (*hwcLayer)->setHdrMetadata(metadata);
+ if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
+ ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
+ uint32_t hwcSlot = 0;
+ sp<GraphicBuffer> hwcBuffer;
+ getBE().mHwcLayers[hwcId].bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot,
+ &hwcBuffer);
auto acquireFence = mConsumer->getCurrentFence();
- getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
- getBE().compositionInfo.mBuffer = mActiveBuffer;
- getBE().compositionInfo.hwc.fence = acquireFence;
+ error = (*hwcLayer)->setBuffer(hwcSlot, hwcBuffer, acquireFence);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
+ getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
}
bool BufferLayer::isOpaque(const Layer::State& s) const {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0c9f0e2..c90024b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -143,7 +143,7 @@
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
- const sp<IBinder>& parentHandle, uint32_t windowType, uint32_t ownerUid,
+ const sp<IBinder>& parentHandle, int32_t windowType, int32_t ownerUid,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
@@ -180,13 +180,13 @@
PixelFormat format;
uint32_t flags;
sp<Layer>* parent;
- uint32_t windowType;
- uint32_t ownerUid;
+ int32_t windowType;
+ int32_t ownerUid;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
- sp<IBinder>* handle, uint32_t windowType, uint32_t ownerUid,
+ sp<IBinder>* handle, int32_t windowType, int32_t ownerUid,
sp<IGraphicBufferProducer>* gbp,
sp<Layer>* parent)
: flinger(flinger), client(client),
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 2aab28f..c7df9f7 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -58,7 +58,7 @@
virtual status_t createSurface(
const String8& name,
uint32_t w, uint32_t h,PixelFormat format, uint32_t flags,
- const sp<IBinder>& parent, uint32_t windowType, uint32_t ownerUid,
+ const sp<IBinder>& parent, int32_t windowType, int32_t ownerUid,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp);
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 5990a61..71975c8 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -77,18 +77,38 @@
const auto& viewport = displayDevice->getViewport();
Region visible = tr.transform(visibleRegion.intersect(viewport));
auto hwcId = displayDevice->getHwcDisplayId();
- getBE().compositionInfo.hwc.visibleRegion = visible;
- getBE().compositionInfo.hwc.dataspace = mDrawingState.dataSpace;
+ auto& hwcInfo = getBE().mHwcLayers[hwcId];
+ auto& hwcLayer = hwcInfo.layer;
+ auto error = (*hwcLayer)->setVisibleRegion(visible);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ visible.dump(LOG_TAG);
+ }
setCompositionType(hwcId, HWC2::Composition::SolidColor);
+ error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
half4 color = getColor();
- getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)),
- static_cast<uint8_t>(std::round(255.0f * color.g)),
- static_cast<uint8_t>(std::round(255.0f * color.b)), 255 };
+ error = (*hwcLayer)->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
+ static_cast<uint8_t>(std::round(255.0f * color.g)),
+ static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
// Clear out the transform, because it doesn't make sense absent a source buffer
- getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
+ error = (*hwcLayer)->setTransform(HWC2::Transform::None);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 92d5e21..fe0b30b 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -57,9 +57,6 @@
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
-static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs,
- &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) >= 3;
-
/*
* Initialize the display to the specified values.
*
@@ -74,72 +71,43 @@
int32_t hwcId,
bool isSecure,
const wp<IBinder>& displayToken,
+ const sp<ANativeWindow>& nativeWindow,
const sp<DisplaySurface>& displaySurface,
- const sp<IGraphicBufferProducer>& producer,
+ std::unique_ptr<RE::Surface> renderSurface,
+ int displayWidth,
+ int displayHeight,
bool supportWideColor,
- bool supportHdr)
+ bool supportHdr,
+ int initialPowerMode)
: lastCompositionHadVisibleLayers(false),
mFlinger(flinger),
mType(type),
mHwcDisplayId(hwcId),
mDisplayToken(displayToken),
+ mNativeWindow(nativeWindow),
mDisplaySurface(displaySurface),
- mSurface{flinger->getRenderEngine().createSurface()},
- mDisplayWidth(),
- mDisplayHeight(),
- mPageFlipCount(),
+ mSurface{std::move(renderSurface)},
+ mDisplayWidth(displayWidth),
+ mDisplayHeight(displayHeight),
+ mPageFlipCount(0),
mIsSecure(isSecure),
mLayerStack(NO_LAYER_STACK),
mOrientation(),
- mPowerMode(HWC_POWER_MODE_OFF),
- mActiveConfig(0)
+ mViewport(Rect::INVALID_RECT),
+ mFrame(Rect::INVALID_RECT),
+ mPowerMode(initialPowerMode),
+ mActiveConfig(0),
+ mActiveColorMode(ColorMode::NATIVE),
+ mDisplayHasWideColor(supportWideColor),
+ mDisplayHasHdr(supportHdr)
{
// clang-format on
- Surface* surface;
- mNativeWindow = surface = new Surface(producer, false);
- ANativeWindow* const window = mNativeWindow.get();
-
- mActiveColorMode = ColorMode::NATIVE;
- mDisplayHasWideColor = supportWideColor;
- mDisplayHasHdr = supportHdr;
-
- /*
- * Create our display's surface
- */
- mSurface->setCritical(mType == DisplayDevice::DISPLAY_PRIMARY);
- mSurface->setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL);
- mSurface->setNativeWindow(window);
- mDisplayWidth = mSurface->queryWidth();
- mDisplayHeight = mSurface->queryHeight();
-
- // Make sure that composition can never be stalled by a virtual display
- // consumer that isn't processing buffers fast enough. We have to do this
- // in two places:
- // * Here, in case the display is composed entirely by HWC.
- // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
- // window's swap interval in eglMakeCurrent, so they'll override the
- // interval we set here.
- if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
- window->setSwapInterval(window, 0);
-
- mPageFlipCount = 0;
- mViewport.makeInvalid();
- mFrame.makeInvalid();
-
- // virtual displays are always considered enabled
- mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
- HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
-
- if (useTripleFramebuffer) {
- surface->allocateBuffers();
- }
}
-DisplayDevice::~DisplayDevice() {
-}
+DisplayDevice::~DisplayDevice() = default;
void DisplayDevice::disconnect(HWComposer& hwc) {
if (mHwcDisplayId >= 0) {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 737971f..fbb0d46 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -77,9 +77,14 @@
int32_t hwcId,
bool isSecure,
const wp<IBinder>& displayToken,
+ const sp<ANativeWindow>& nativeWindow,
const sp<DisplaySurface>& displaySurface,
- const sp<IGraphicBufferProducer>& producer,
- bool supportWideColor, bool supportHdr);
+ std::unique_ptr<RE::Surface> renderSurface,
+ int displayWidth,
+ int displayHeight,
+ bool supportWideColor,
+ bool supportHdr,
+ int initialPowerMode);
// clang-format on
~DisplayDevice();
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 381da63..0c77aba 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -145,32 +145,32 @@
void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
if (connection == Connection::Connected) {
- auto display = getDisplayById(displayId);
- if (display) {
- if (display->isConnected()) {
- ALOGW("Attempt to hotplug connect display %" PRIu64
- " , which is already connected.", displayId);
- } else {
- display->setConnected(true);
- }
- } else {
- DisplayType displayType;
- auto intError = mComposer->getDisplayType(displayId,
- reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
- &displayType));
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
- "Aborting hotplug attempt.",
- displayId, to_string(error).c_str(), intError);
- return;
- }
-
- auto newDisplay = std::make_unique<Display>(
- *mComposer.get(), mCapabilities, displayId, displayType);
- newDisplay->setConnected(true);
- mDisplays.emplace(displayId, std::move(newDisplay));
+ // If we get a hotplug connected event for a display we already have,
+ // destroy the display and recreate it. This will force us to requery
+ // the display params and recreate all layers on that display.
+ auto oldDisplay = getDisplayById(displayId);
+ if (oldDisplay != nullptr && oldDisplay->isConnected()) {
+ ALOGI("Hotplug connecting an already connected display."
+ " Clearing old display state.");
}
+ mDisplays.erase(displayId);
+
+ DisplayType displayType;
+ auto intError = mComposer->getDisplayType(displayId,
+ reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
+ &displayType));
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
+ "Aborting hotplug attempt.",
+ displayId, to_string(error).c_str(), intError);
+ return;
+ }
+
+ auto newDisplay = std::make_unique<Display>(
+ *mComposer.get(), mCapabilities, displayId, displayType);
+ newDisplay->setConnected(true);
+ mDisplays.emplace(displayId, std::move(newDisplay));
} else if (connection == Connection::Disconnected) {
// The display will later be destroyed by a call to
// destroyDisplay(). For now we just mark it disconnected.
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index b072213..615270f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -490,6 +490,8 @@
hwcInfo.forceClientComposition = true;
}
+ auto& hwcLayer = hwcInfo.layer;
+
// this gives us only the "orientation" component of the transform
const State& s(getDrawingState());
auto blendMode = HWC2::BlendMode::None;
@@ -497,7 +499,12 @@
blendMode =
mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
}
- getBE().compositionInfo.hwc.blendMode = blendMode;
+ auto error = (*hwcLayer)->setBlendMode(blendMode);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[%s] Failed to set blend mode %s:"
+ " %s (%d)",
+ mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
@@ -540,27 +547,51 @@
}
const Transform& tr(displayDevice->getTransform());
Rect transformedFrame = tr.transform(frame);
- getBE().compositionInfo.hwc.displayFrame = transformedFrame;
+ error = (*hwcLayer)->setDisplayFrame(transformedFrame);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
+ transformedFrame.left, transformedFrame.top, transformedFrame.right,
+ transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
+ } else {
+ hwcInfo.displayFrame = transformedFrame;
+ }
FloatRect sourceCrop = computeCrop(displayDevice);
- getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
+ error = (*hwcLayer)->setSourceCrop(sourceCrop);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
+ "%s (%d)",
+ mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ } else {
+ hwcInfo.sourceCrop = sourceCrop;
+ }
float alpha = static_cast<float>(getAlpha());
- getBE().compositionInfo.hwc.alpha = alpha;
+ error = (*hwcLayer)->setPlaneAlpha(alpha);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[%s] Failed to set plane alpha %.3f: "
+ "%s (%d)",
+ mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
- getBE().compositionInfo.hwc.z = z;
+ error = (*hwcLayer)->setZOrder(z);
+ ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
+ to_string(error).c_str(), static_cast<int32_t>(error));
int type = s.type;
int appId = s.appId;
sp<Layer> parent = mDrawingParent.promote();
if (parent.get()) {
auto& parentState = parent->getDrawingState();
- type = parentState.type;
- appId = parentState.appId;
+ if (parentState.type >= 0 || parentState.appId >= 0) {
+ type = parentState.type;
+ appId = parentState.appId;
+ }
}
- getBE().compositionInfo.hwc.type = type;
- getBE().compositionInfo.hwc.appId = appId;
+ error = (*hwcLayer)->setInfo(type, appId);
+ ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
+ static_cast<int32_t>(error));
/*
* Transformations are applied in this order:
@@ -607,109 +638,12 @@
} else {
auto transform = static_cast<HWC2::Transform>(orientation);
hwcInfo.transform = transform;
- getBE().compositionInfo.hwc.transform = transform;
- }
-}
-
-void Layer::configureHwcLayer(const sp<const DisplayDevice>& displayDevice) {
- ATRACE_CALL();
-
- auto hwcId = displayDevice->getHwcDisplayId();
- auto& hwcInfo = getBE().mHwcLayers[hwcId];
- auto& hwcLayer = hwcInfo.layer;
-
- auto error = (*hwcLayer)->setBlendMode(getBE().compositionInfo.hwc.blendMode);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set blend mode %s:"
- " %s (%d)",
- mName.string(),
- to_string(getBE().compositionInfo.hwc.blendMode).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setDisplayFrame(getBE().compositionInfo.hwc.displayFrame);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set the display frame [%d, %d, %d, %d] %s (%d)",
- mName.string(),
- getBE().compositionInfo.hwc.displayFrame.left,
- getBE().compositionInfo.hwc.displayFrame.right,
- getBE().compositionInfo.hwc.displayFrame.top,
- getBE().compositionInfo.hwc.displayFrame.bottom,
- to_string(error).c_str(), static_cast<int32_t>(error));
-
-
- error = (*hwcLayer)->setPlaneAlpha(getBE().compositionInfo.hwc.alpha);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set plane alpha %.3f: "
- "%s (%d)",
- mName.string(), getBE().compositionInfo.hwc.alpha,
- to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setSourceCrop(getBE().compositionInfo.hwc.sourceCrop);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: %s (%d)",
- mName.string(),
- getBE().compositionInfo.hwc.sourceCrop.left,
- getBE().compositionInfo.hwc.sourceCrop.right,
- getBE().compositionInfo.hwc.sourceCrop.top,
- getBE().compositionInfo.hwc.sourceCrop.bottom,
- to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setTransform(getBE().compositionInfo.hwc.transform);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set transform %s: "
- "%s (%d)",
- mName.string(),
- to_string(getBE().compositionInfo.hwc.transform).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setZOrder(getBE().compositionInfo.hwc.z);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set Z %u: %s (%d)",
- mName.string(), getBE().compositionInfo.hwc.z,
- to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setInfo(getBE().compositionInfo.hwc.type, getBE().compositionInfo.hwc.appId);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set info (%d)",
- mName.string(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setVisibleRegion(getBE().compositionInfo.hwc.visibleRegion);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set visible region: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setSurfaceDamage(getBE().compositionInfo.hwc.surfaceDamage);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set surface damage: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setCompositionType(getBE().compositionInfo.compositionType);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set composition type: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setDataspace(getBE().compositionInfo.hwc.dataspace);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set dataspace: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
-
- error = (*hwcLayer)->setHdrMetadata(getBE().compositionInfo.hwc.hdrMetadata);
- if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
- ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-
- error = (*hwcLayer)->setColor(getBE().compositionInfo.hwc.color);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set color: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
-
- if (getBE().compositionInfo.hwc.fence) {
- error = (*hwcLayer)->setBuffer(getBE().compositionInfo.mBufferSlot,
- getBE().compositionInfo.mBuffer, getBE().compositionInfo.hwc.fence);
+ auto error = (*hwcLayer)->setTransform(transform);
ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set buffer: %s (%d)",
- mName.string(), to_string(error).c_str(), static_cast<int32_t>(error));
+ "[%s] Failed to set transform %s: "
+ "%s (%d)",
+ mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
}
}
@@ -1378,7 +1312,7 @@
return true;
}
-void Layer::setInfo(uint32_t type, uint32_t appId) {
+void Layer::setInfo(int32_t type, int32_t appId) {
mCurrentState.appId = appId;
mCurrentState.type = type;
mCurrentState.modified = true;
@@ -1556,11 +1490,12 @@
result.appendFormat(" %s\n", name.string());
const Layer::State& layerState(getDrawingState());
+ const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(hwcId);
result.appendFormat(" %10d | ", layerState.z);
result.appendFormat("%10s | ", to_string(getCompositionType(hwcId)).c_str());
- const Rect& frame = getBE().compositionInfo.hwc.displayFrame;
+ const Rect& frame = hwcInfo.displayFrame;
result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
- const FloatRect& crop = getBE().compositionInfo.hwc.sourceCrop;
+ const FloatRect& crop = hwcInfo.sourceCrop;
result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right, crop.bottom);
result.append("- - - - - - - - - - - - - - - - - - - - ");
@@ -1983,6 +1918,8 @@
layerInfo->set_queued_frames(getQueuedFrameCount());
layerInfo->set_refresh_pending(isBufferLatched());
+ layerInfo->set_window_type(state.type);
+ layerInfo->set_app_id(state.appId);
}
void Layer::writeToProto(LayerProto* layerInfo, int32_t hwcId) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 87f9489..c1a4dcf 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -146,8 +146,8 @@
Region requestedTransparentRegion;
android_dataspace dataSpace;
- uint32_t appId;
- uint32_t type;
+ int32_t appId;
+ int32_t type;
// If non-null, a Surface this Surface's Z-order is interpreted relative to.
wp<Layer> zOrderRelativeOf;
@@ -228,7 +228,7 @@
void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
bool setOverrideScalingMode(int32_t overrideScalingMode);
- void setInfo(uint32_t type, uint32_t appId);
+ void setInfo(int32_t type, int32_t appId);
bool reparentChildren(const sp<IBinder>& layer);
void reparentChildrenForDrawing(const sp<Layer>& layer);
bool reparent(const sp<IBinder>& newParentHandle);
@@ -309,7 +309,6 @@
virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z);
- void configureHwcLayer(const sp<const DisplayDevice>& displayDevice);
void forceClientComposition(int32_t hwcId);
bool getForceClientComposition(int32_t hwcId);
virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index 06c88a4..854cdd6 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -19,7 +19,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <gui/HdrMetadata.h>
#include <ui/Region.h>
#include "SurfaceFlinger.h"
@@ -81,7 +80,6 @@
sp<NativeHandle> sidebandStream;
android_dataspace dataspace;
hwc_color_t color;
- HdrMetadata hdrMetadata;
} hwc;
struct {
Mesh* mesh;
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index ea2542c..ad1043f 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -56,11 +56,11 @@
}
void LayerStats::traverseLayerTreeStatsLocked(
- const std::vector<const LayerProtoParser::Layer*>& layerTree,
+ std::vector<std::unique_ptr<LayerProtoParser::Layer>> layerTree,
const LayerProtoParser::LayerGlobal* layerGlobal) {
- for (auto layer : layerTree) {
+ for (std::unique_ptr<LayerProtoParser::Layer>& layer : layerTree) {
if (!layer) continue;
- traverseLayerTreeStatsLocked(layer->children, layerGlobal);
+ traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal);
std::string key =
base::StringPrintf("%s,%s,%s,%s,%s,%s,%s,%s,%s",
destinationLocation(layer->hwcFrame.left,
@@ -71,7 +71,7 @@
layerGlobal->resolution[0], true),
destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
layerGlobal->resolution[1], false),
- layer->type.c_str(), scaleRatioWH(layer).c_str(),
+ layer->type.c_str(), scaleRatioWH(layer.get()).c_str(),
layerTransform(layer->hwcTransform), layer->pixelFormat.c_str(),
layer->dataspace.c_str());
mLayerStatsMap[key]++;
@@ -83,8 +83,7 @@
auto layerGlobal = LayerProtoParser::generateLayerGlobalInfo(layersProto);
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
std::lock_guard<std::mutex> lock(mMutex);
- traverseLayerTreeStatsLocked(layerTree, &layerGlobal);
- LayerProtoParser::destroyLayerTree(layerTree);
+ traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal);
}
void LayerStats::dump(String8& result) {
diff --git a/services/surfaceflinger/LayerStats.h b/services/surfaceflinger/LayerStats.h
index 1924110..9522725 100644
--- a/services/surfaceflinger/LayerStats.h
+++ b/services/surfaceflinger/LayerStats.h
@@ -37,8 +37,9 @@
private:
// Traverse layer tree to get all visible layers' stats
- void traverseLayerTreeStatsLocked(const std::vector<const LayerProtoParser::Layer*>& layerTree,
- const LayerProtoParser::LayerGlobal* layerGlobal);
+ void traverseLayerTreeStatsLocked(
+ std::vector<std::unique_ptr<LayerProtoParser::Layer>> layerTree,
+ const LayerProtoParser::LayerGlobal* layerGlobal);
// Convert layer's top-left position into 8x8 percentage of the display
static const char* destinationLocation(int32_t location, int32_t range, bool isHorizontal);
// Convert layer's size into 8x8 percentage of the display
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 7a43ea9..6a34981 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -305,15 +305,24 @@
if (needs.hasToneMapping()) {
fs << R"__SHADER__(
- float ToneMapChannel(const float color) {
+ float CalculateY(const vec3 color) {
+ // BT2020 standard uses the unadjusted KR = 0.2627,
+ // KB = 0.0593 luminance interpretation for RGB conversion.
+ return color.r * 0.262700 + color.g * 0.677998 +
+ color.b * 0.059302;
+ }
+ vec3 ToneMap(const vec3 color) {
const float maxLumi = 10000.0;
const float maxMasteringLumi = 1000.0;
const float maxContentLumi = 1000.0;
const float maxInLumi = min(maxMasteringLumi, maxContentLumi);
const float maxOutLumi = 500.0;
+ // Calculate Y value in XYZ color space.
+ float colorY = CalculateY(color);
+
// convert to nits first
- float nits = color * maxLumi;
+ float nits = colorY * maxLumi;
// clamp to max input luminance
nits = clamp(nits, 0.0, maxInLumi);
@@ -360,12 +369,8 @@
}
// convert back to [0.0, 1.0]
- return nits / maxOutLumi;
- }
-
- vec3 ToneMap(const vec3 color) {
- return vec3(ToneMapChannel(color.r), ToneMapChannel(color.g),
- ToneMapChannel(color.b));
+ float targetY = nits / maxOutLumi;
+ return color * (targetY / max(1e-6, colorY));
}
)__SHADER__";
} else {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8d5c496..f709534 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -154,6 +154,32 @@
return std::string(value) == "true";
}
+NativeWindowSurface::~NativeWindowSurface() = default;
+
+namespace impl {
+
+class NativeWindowSurface final : public android::NativeWindowSurface {
+public:
+ static std::unique_ptr<android::NativeWindowSurface> create(
+ const sp<IGraphicBufferProducer>& producer) {
+ return std::make_unique<NativeWindowSurface>(producer);
+ }
+
+ explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer)
+ : surface(new Surface(producer, false)) {}
+
+ ~NativeWindowSurface() override = default;
+
+private:
+ sp<ANativeWindow> getNativeWindow() const override { return surface; }
+
+ void preallocateBuffers() override { surface->allocateBuffers(); }
+
+ sp<Surface> surface;
+};
+
+} // namespace impl
+
SurfaceFlingerBE::SurfaceFlingerBE()
: mHwcServiceName(getHwcServiceName()),
mRenderEngine(nullptr),
@@ -194,7 +220,8 @@
mNumLayers(0),
mVrFlingerRequestsDisplay(false),
mMainThreadId(std::this_thread::get_id()),
- mCreateBufferQueue(&BufferQueue::createBufferQueue) {}
+ mCreateBufferQueue(&BufferQueue::createBufferQueue),
+ mCreateNativeWindowSurface(&impl::NativeWindowSurface::create) {}
SurfaceFlinger::SurfaceFlinger() : SurfaceFlinger(SkipInitialization) {
ALOGI("SurfaceFlinger is starting");
@@ -647,7 +674,6 @@
// set initial conditions (e.g. unblank default device)
initializeDisplays();
- ALOGV("Displays initialized");
getBE().mRenderEngine->primeCache();
@@ -1972,18 +1998,6 @@
mPreviousColorMatrix = colorMatrix;
- for (size_t dpy = 0; dpy < mDisplays.size(); dpy++) {
- sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
- const auto hwcId = displayDevice->getHwcDisplayId();
- if (hwcId >= 0) {
- const Vector<sp<Layer>>& currentLayers(
- displayDevice->getVisibleLayersSortedByZ());
- for (auto& layer : currentLayers) {
- layer->configureHwcLayer(displayDevice);
- }
- }
- }
-
for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
auto& displayDevice = mDisplays[displayId];
if (!displayDevice->isDisplayOn()) {
@@ -2113,7 +2127,7 @@
}
DisplayDevice::DisplayType SurfaceFlinger::determineDisplayType(hwc2_display_t display,
- HWC2::Connection connection) const {
+ HWC2::Connection connection) const {
// Figure out whether the event is for the primary display or an
// external display by matching the Hwc display id against one for a
// connected display. If we did not find a match, we then check what
@@ -2154,16 +2168,16 @@
getBE().mHwc->onHotplug(event.display, displayType, event.connection);
if (event.connection == HWC2::Connection::Connected) {
- ALOGV("Creating built in display %d", displayType);
- ALOGW_IF(mBuiltinDisplays[displayType],
- "Overwriting display token for display type %d", displayType);
- mBuiltinDisplays[displayType] = new BBinder();
- // All non-virtual displays are currently considered secure.
- DisplayDeviceState info(displayType, true);
- info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?
- "Built-in Screen" : "External Screen";
- mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
- mInterceptor->saveDisplayCreation(info);
+ if (!mBuiltinDisplays[displayType].get()) {
+ ALOGV("Creating built in display %d", displayType);
+ mBuiltinDisplays[displayType] = new BBinder();
+ // All non-virtual displays are currently considered secure.
+ DisplayDeviceState info(displayType, true);
+ info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?
+ "Built-in Screen" : "External Screen";
+ mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
+ mInterceptor->saveDisplayCreation(info);
+ }
} else {
ALOGV("Removing built in display %d", displayType);
@@ -2182,6 +2196,84 @@
mPendingHotplugEvents.clear();
}
+sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
+ const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
+ const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
+ bool hasWideColorSupport = false;
+ if (hasWideColorDisplay) {
+ std::vector<ColorMode> modes = getHwComposer().getColorModes(state.type);
+ for (ColorMode colorMode : modes) {
+ switch (colorMode) {
+ case ColorMode::DISPLAY_P3:
+ case ColorMode::ADOBE_RGB:
+ case ColorMode::DCI_P3:
+ hasWideColorSupport = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ bool hasHdrSupport = false;
+ std::unique_ptr<HdrCapabilities> hdrCapabilities =
+ getHwComposer().getHdrCapabilities(state.type);
+ if (hdrCapabilities) {
+ const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes();
+ auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10);
+ hasHdrSupport = iter != types.cend();
+ }
+
+ auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
+ auto nativeWindow = nativeWindowSurface->getNativeWindow();
+
+ /*
+ * Create our display's surface
+ */
+ std::unique_ptr<RE::Surface> renderSurface = getRenderEngine().createSurface();
+ renderSurface->setCritical(state.type == DisplayDevice::DISPLAY_PRIMARY);
+ renderSurface->setAsync(state.type >= DisplayDevice::DISPLAY_VIRTUAL);
+ renderSurface->setNativeWindow(nativeWindow.get());
+ const int displayWidth = renderSurface->queryWidth();
+ const int displayHeight = renderSurface->queryHeight();
+
+ // Make sure that composition can never be stalled by a virtual display
+ // consumer that isn't processing buffers fast enough. We have to do this
+ // in two places:
+ // * Here, in case the display is composed entirely by HWC.
+ // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
+ // window's swap interval in eglMakeCurrent, so they'll override the
+ // interval we set here.
+ if (state.type >= DisplayDevice::DISPLAY_VIRTUAL) {
+ nativeWindow->setSwapInterval(nativeWindow.get(), 0);
+ }
+
+ // virtual displays are always considered enabled
+ auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL
+ : HWC_POWER_MODE_OFF;
+
+ sp<DisplayDevice> hw =
+ new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
+ dispSurface, std::move(renderSurface), displayWidth, displayHeight,
+ hasWideColorSupport, hasHdrSupport, initialPowerMode);
+
+ if (maxFrameBufferAcquiredBuffers >= 3) {
+ nativeWindowSurface->preallocateBuffers();
+ }
+
+ ColorMode defaultColorMode = ColorMode::NATIVE;
+ if (hasWideColorSupport) {
+ defaultColorMode = ColorMode::SRGB;
+ }
+ setActiveColorModeInternal(hw, defaultColorMode);
+ hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
+ hw->setLayerStack(state.layerStack);
+ hw->setProjection(state.orientation, state.viewport, state.frame);
+ hw->setDisplayName(state.displayName);
+
+ return hw;
+}
+
void SurfaceFlinger::processDisplayChangesLocked() {
// here we take advantage of Vector's copy-on-write semantics to
// improve performance by skipping the transaction entirely when
@@ -2304,50 +2396,10 @@
}
const wp<IBinder>& display(curr.keyAt(i));
-
if (dispSurface != nullptr) {
- bool hasWideColorSupport = false;
- if (hasWideColorDisplay) {
- std::vector<ColorMode> modes =
- getHwComposer().getColorModes(state.type);
- for (ColorMode colorMode : modes) {
- switch (colorMode) {
- case ColorMode::DISPLAY_P3:
- case ColorMode::ADOBE_RGB:
- case ColorMode::DCI_P3:
- hasWideColorSupport = true;
- break;
- default:
- break;
- }
- }
- }
-
- bool hasHdrSupport = false;
- std::unique_ptr<HdrCapabilities> hdrCapabilities =
- getHwComposer().getHdrCapabilities(state.type);
- if (hdrCapabilities) {
- const std::vector<int32_t> types = hdrCapabilities->getSupportedHdrTypes();
- auto iter = std::find(types.cbegin(), types.cend(), HAL_HDR_HDR10);
- hasHdrSupport = iter != types.cend();
- }
-
- sp<DisplayDevice> hw =
- new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
- dispSurface, producer, hasWideColorSupport,
- hasHdrSupport);
-
- ColorMode defaultColorMode = ColorMode::NATIVE;
- if (hasWideColorSupport) {
- defaultColorMode = ColorMode::SRGB;
- }
- setActiveColorModeInternal(hw, defaultColorMode);
- hw->setCompositionDataSpace(HAL_DATASPACE_UNKNOWN);
- hw->setLayerStack(state.layerStack);
- hw->setProjection(state.orientation, state.viewport, state.frame);
- hw->setDisplayName(state.displayName);
-
- mDisplays.add(display, hw);
+ mDisplays.add(display,
+ setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface,
+ producer));
if (!state.isVirtualDisplay()) {
mEventThread->onHotplugReceived(state.type, true);
}
@@ -2775,7 +2827,6 @@
}
bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId);
- ATRACE_INT("hasClientComposition", hasClientComposition);
if (hasClientComposition) {
ALOGV("hasClientComposition");
@@ -3353,7 +3404,7 @@
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
- uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
+ int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
if (int32_t(w|h) < 0) {
@@ -4062,7 +4113,7 @@
LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current);
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
- result.append(LayerProtoParser::layersToString(layerTree).c_str());
+ result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str());
/*
* Dump Display state
@@ -4886,6 +4937,7 @@
}; // namespace android
+
#if defined(__gl_h_)
#error "don't include gl/gl.h in this file"
#endif
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c7ffea7..99bbb13 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -121,6 +121,19 @@
eTransactionMask = 0x07
};
+// A thin interface to abstract creating instances of Surface (gui/Surface.h) to
+// use as a NativeWindow.
+class NativeWindowSurface {
+public:
+ virtual ~NativeWindowSurface();
+
+ // Gets the NativeWindow to use for the surface.
+ virtual sp<ANativeWindow> getNativeWindow() const = 0;
+
+ // Indicates that the surface should allocate its buffers now.
+ virtual void preallocateBuffers() = 0;
+};
+
class SurfaceFlingerBE
{
public:
@@ -491,7 +504,7 @@
*/
status_t createLayer(const String8& name, const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
- uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
+ int32_t windowType, int32_t ownerUid, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent);
status_t createBufferLayer(const sp<Client>& client, const String8& name,
@@ -650,6 +663,10 @@
*/
DisplayDevice::DisplayType determineDisplayType(hwc2_display_t display,
HWC2::Connection connection) const;
+ sp<DisplayDevice> setupNewDisplayDeviceInternal(const wp<IBinder>& display, int hwcId,
+ const DisplayDeviceState& state,
+ const sp<DisplaySurface>& dispSurface,
+ const sp<IGraphicBufferProducer>& producer);
void processDisplayChangesLocked();
void processDisplayHotplugEventsLocked();
@@ -843,6 +860,10 @@
bool /* consumerIsSurfaceFlinger */)>;
CreateBufferQueueFunction mCreateBufferQueue;
+ using CreateNativeWindowSurfaceFunction =
+ std::function<std::unique_ptr<NativeWindowSurface>(const sp<IGraphicBufferProducer>&)>;
+ CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
+
SurfaceFlingerBE mBE;
};
}; // namespace android
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 7483abd..b10e07b 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include <android-base/stringprintf.h>
#include <layerproto/LayerProtoParser.h>
#include <ui/DebugUtils.h>
@@ -24,7 +23,7 @@
namespace android {
namespace surfaceflinger {
-bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
+bool sortLayers(LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
uint32_t ls = lhs->layerStack;
uint32_t rs = rhs->layerStack;
if (ls != rs) return ls < rs;
@@ -38,33 +37,30 @@
return lhs->id < rhs->id;
}
+bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs,
+ const std::unique_ptr<LayerProtoParser::Layer>& rhs) {
+ return sortLayers(lhs.get(), rhs.get());
+}
+
const LayerProtoParser::LayerGlobal LayerProtoParser::generateLayerGlobalInfo(
const LayersProto& layersProto) {
return {{layersProto.resolution().w(), layersProto.resolution().h()}};
}
-void LayerProtoParser::destroyLayerTree(
- const std::vector<const LayerProtoParser::Layer*>& layerTree) {
- for (auto layer : layerTree) {
- destroyLayerTree(layer->children);
- delete layer;
- }
-}
-
-std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree(
+std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree(
const LayersProto& layersProto) {
- auto layerMap = generateMap(layersProto);
+ std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto);
+ std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers;
- std::vector<const Layer*> layers;
- std::for_each(layerMap.begin(), layerMap.end(),
- [&](const std::pair<const int32_t, Layer*>& ref) {
- if (ref.second->parent == nullptr) {
- // only save top level layers
- layers.push_back(ref.second);
- }
- });
+ for (std::pair<int32_t, Layer*> kv : layerMap) {
+ if (kv.second->parent == nullptr) {
+ // Make unique_ptr for top level layers since they are not children. This ensures there
+ // will only be one unique_ptr made for each layer.
+ layers.push_back(std::unique_ptr<Layer>(kv.second));
+ }
+ }
- std::sort(layers.begin(), layers.end(), sortLayers);
+ std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs);
return layers;
}
@@ -118,6 +114,8 @@
layer->hwcFrame = generateRect(layerProto.hwc_frame());
layer->hwcCrop = generateFloatRect(layerProto.hwc_crop());
layer->hwcTransform = layerProto.hwc_transform();
+ layer->windowType = layerProto.window_type();
+ layer->appId = layerProto.app_id();
return layer;
}
@@ -181,63 +179,61 @@
for (int i = 0; i < layerProto.children_size(); i++) {
if (layerMap.count(layerProto.children(i)) > 0) {
- auto childLayer = layerMap[layerProto.children(i)];
- currLayer->children.push_back(childLayer);
+ // Only make unique_ptrs for children since they are guaranteed to be unique, only one
+ // parent per child. This ensures there will only be one unique_ptr made for each layer.
+ currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)]));
}
}
for (int i = 0; i < layerProto.relatives_size(); i++) {
if (layerMap.count(layerProto.relatives(i)) > 0) {
- auto relativeLayer = layerMap[layerProto.relatives(i)];
- currLayer->relatives.push_back(relativeLayer);
+ currLayer->relatives.push_back(layerMap[layerProto.relatives(i)]);
}
}
if (layerProto.has_parent()) {
if (layerMap.count(layerProto.parent()) > 0) {
- auto parentLayer = layerMap[layerProto.parent()];
- currLayer->parent = parentLayer;
+ currLayer->parent = layerMap[layerProto.parent()];
}
}
if (layerProto.has_z_order_relative_of()) {
if (layerMap.count(layerProto.z_order_relative_of()) > 0) {
- auto relativeLayer = layerMap[layerProto.z_order_relative_of()];
- currLayer->zOrderRelativeOf = relativeLayer;
+ currLayer->zOrderRelativeOf = layerMap[layerProto.z_order_relative_of()];
}
}
}
std::string LayerProtoParser::layersToString(
- const std::vector<const LayerProtoParser::Layer*> layers) {
+ std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) {
std::string result;
- for (const LayerProtoParser::Layer* layer : layers) {
+ for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) {
if (layer->zOrderRelativeOf != nullptr) {
continue;
}
- result.append(layerToString(layer).c_str());
+ result.append(layerToString(layer.get()).c_str());
}
return result;
}
-std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
+std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) {
std::string result;
- std::vector<const Layer*> traverse(layer->relatives);
- for (const LayerProtoParser::Layer* child : layer->children) {
+ std::vector<Layer*> traverse(layer->relatives);
+ for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) {
if (child->zOrderRelativeOf != nullptr) {
continue;
}
- traverse.push_back(child);
+ traverse.push_back(child.get());
}
std::sort(traverse.begin(), traverse.end(), sortLayers);
size_t i = 0;
for (; i < traverse.size(); i++) {
- const auto& relative = traverse[i];
+ auto& relative = traverse[i];
if (relative->z >= 0) {
break;
}
@@ -246,7 +242,7 @@
result.append(layer->to_string().c_str());
result.append("\n");
for (; i < traverse.size(); i++) {
- const auto& relative = traverse[i];
+ auto& relative = traverse[i];
result.append(layerToString(relative).c_str());
}
@@ -309,7 +305,8 @@
StringAppendF(&result, " zOrderRelativeOf=%s\n",
zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str());
- StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d", queuedFrames, refreshPending);
+ StringAppendF(&result, " queued-frames=%d, mRefreshPending=%d,", queuedFrames, refreshPending);
+ StringAppendF(&result, " windowType=%d, appId=%d", windowType, appId);
return result;
}
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index 4747275..fd893da 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -19,6 +19,7 @@
#include <math/vec4.h>
+#include <memory>
#include <unordered_map>
#include <vector>
@@ -79,8 +80,8 @@
public:
int32_t id;
std::string name;
- std::vector<const Layer*> children;
- std::vector<const Layer*> relatives;
+ std::vector<std::unique_ptr<Layer>> children;
+ std::vector<Layer*> relatives;
std::string type;
LayerProtoParser::Region transparentRegion;
LayerProtoParser::Region visibleRegion;
@@ -109,6 +110,8 @@
LayerProtoParser::Rect hwcFrame;
LayerProtoParser::FloatRect hwcCrop;
int32_t hwcTransform;
+ int32_t windowType;
+ int32_t appId;
std::string to_string() const;
};
@@ -119,9 +122,8 @@
};
static const LayerGlobal generateLayerGlobalInfo(const LayersProto& layersProto);
- static std::vector<const Layer*> generateLayerTree(const LayersProto& layersProto);
- static void destroyLayerTree(const std::vector<const LayerProtoParser::Layer*>& layerTree);
- static std::string layersToString(const std::vector<const LayerProtoParser::Layer*> layers);
+ static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto);
+ static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers);
private:
static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto);
@@ -135,7 +137,7 @@
static void updateChildrenAndRelative(const LayerProto& layerProto,
std::unordered_map<int32_t, Layer*>& layerMap);
- static std::string layerToString(const LayerProtoParser::Layer* layer);
+ static std::string layerToString(LayerProtoParser::Layer* layer);
};
} // namespace surfaceflinger
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index e232f05..6675aae 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -71,6 +71,8 @@
optional FloatRectProto hwc_crop = 31;
// The layer's composer backend transform
optional int32 hwc_transform = 32;
+ optional int32 window_type = 33;
+ optional int32 app_id = 34;
}
message PositionProto {
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 7d3da32..7523399 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -33,6 +33,7 @@
"libEGL",
"libGLESv2",
"libgui",
+ "liblayers_proto",
"liblog",
"libprotobuf-cpp-full",
"libui",
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
index 33dd2f5..4577153 100644
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -22,7 +22,7 @@
#include <thread>
#include <functional>
-
+#include <layerproto/LayerProtoParser.h>
namespace android {
@@ -47,4 +47,66 @@
}
}
+surfaceflinger::LayersProto generateLayerProto() {
+ surfaceflinger::LayersProto layersProto;
+ std::array<surfaceflinger::LayerProto*, 10> layers = {};
+ for (size_t i = 0; i < layers.size(); ++i) {
+ layers[i] = layersProto.add_layers();
+ layers[i]->set_id(i);
+ }
+
+ layers[0]->add_children(1);
+ layers[1]->set_parent(0);
+ layers[0]->add_children(2);
+ layers[2]->set_parent(0);
+ layers[0]->add_children(3);
+ layers[3]->set_parent(0);
+ layers[2]->add_children(4);
+ layers[4]->set_parent(2);
+ layers[3]->add_children(5);
+ layers[5]->set_parent(3);
+ layers[5]->add_children(6);
+ layers[6]->set_parent(5);
+ layers[5]->add_children(7);
+ layers[7]->set_parent(5);
+ layers[6]->add_children(8);
+ layers[8]->set_parent(6);
+
+ layers[4]->set_z_order_relative_of(3);
+ layers[3]->add_relatives(4);
+ layers[8]->set_z_order_relative_of(9);
+ layers[9]->add_relatives(8);
+ layers[3]->set_z_order_relative_of(1);
+ layers[1]->add_relatives(3);
+
+/* ----------------------------
+ * - 0 - - 9 -
+ * / | \
+ * 1 2 3(1)
+ * | |
+ * 4(3) 5
+ * / \
+ * 6 7
+ * |
+ * 8(9)
+ * -------------------------- */
+
+ return layersProto;
+}
+
+TEST(LayerProtoStress, mem_info) {
+ std::string cmd = "dumpsys meminfo ";
+ cmd += std::to_string(getpid());
+ system(cmd.c_str());
+ for (int i = 0; i < 100000; i++) {
+ surfaceflinger::LayersProto layersProto = generateLayerProto();
+ auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
+ // Allow some layerTrees to just fall out of scope (instead of std::move)
+ if (i % 2) {
+ surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree));
+ }
+ }
+ system(cmd.c_str());
+}
+
}
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 36bc80f..8ffc5ad 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -28,6 +28,7 @@
"MockGraphicBufferProducer.cpp",
"MockMessageQueue.cpp",
"MockNativeWindow.cpp",
+ "MockNativeWindowSurface.cpp",
"MockRenderEngine.cpp",
"MockSurfaceInterceptor.cpp",
],
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 48b9e92..c048c58 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -21,12 +21,19 @@
#include <gtest/gtest.h>
#include <log/log.h>
+#include "system/window.h"
#include "MockComposer.h"
+#include "MockDisplaySurface.h"
+#include "MockEventControlThread.h"
#include "MockEventThread.h"
#include "MockGraphicBufferConsumer.h"
#include "MockGraphicBufferProducer.h"
+#include "MockMessageQueue.h"
+#include "MockNativeWindow.h"
+#include "MockNativeWindowSurface.h"
#include "MockRenderEngine.h"
+#include "MockSurfaceInterceptor.h"
#include "TestableSurfaceFlinger.h"
namespace android {
@@ -39,41 +46,119 @@
using testing::Return;
using testing::SetArgPointee;
+using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::Hdr;
using android::Hwc2::Error;
using android::Hwc2::IComposer;
using android::Hwc2::IComposerClient;
using HWC2Display = TestableSurfaceFlinger::HWC2Display;
+using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
constexpr int32_t DEFAULT_REFRESH_RATE = 1666666666;
constexpr int32_t DEFAULT_DPI = 320;
+constexpr int DEFAULT_CONFIG_ID = 0;
+
class DisplayTransactionTest : public testing::Test {
protected:
DisplayTransactionTest();
~DisplayTransactionTest() override;
- void setupComposer(int virtualDisplayCount);
- void setupPrimaryDisplay(int width, int height);
+ // --------------------------------------------------------------------
+ // Precondition helpers
- void expectFramebufferQueuePairCreation(int width, int height);
+ void setupComposer(int virtualDisplayCount);
+ void setupFakeHwcDisplay(hwc2_display_t displayId, DisplayDevice::DisplayType type, int width,
+ int height);
+
+ struct FakeDisplayDeviceFactory {
+ public:
+ FakeDisplayDeviceFactory(TestableSurfaceFlinger& flinger, sp<BBinder>& displayToken,
+ DisplayDevice::DisplayType type, int hwcId)
+ : mFlinger(flinger), mDisplayToken(displayToken), mType(type), mHwcId(hwcId) {}
+
+ sp<DisplayDevice> build() {
+ return new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, false, mDisplayToken,
+ mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
+ 0, false, false, HWC_POWER_MODE_NORMAL);
+ }
+
+ FakeDisplayDeviceFactory& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
+ mNativeWindow = nativeWindow;
+ return *this;
+ }
+
+ FakeDisplayDeviceFactory& setDisplaySurface(const sp<DisplaySurface>& displaySurface) {
+ mDisplaySurface = displaySurface;
+ return *this;
+ }
+
+ FakeDisplayDeviceFactory& setRenderSurface(std::unique_ptr<RE::Surface> renderSurface) {
+ mRenderSurface = std::move(renderSurface);
+ return *this;
+ }
+
+ TestableSurfaceFlinger& mFlinger;
+ sp<BBinder>& mDisplayToken;
+ DisplayDevice::DisplayType mType;
+ int mHwcId;
+ sp<ANativeWindow> mNativeWindow;
+ sp<DisplaySurface> mDisplaySurface;
+ std::unique_ptr<RE::Surface> mRenderSurface;
+ };
+
+ sp<BBinder> setupFakeExistingPhysicalDisplay(hwc2_display_t displayId,
+ DisplayDevice::DisplayType type);
+
+ void setupFakeBufferQueueFactory();
+ void setupFakeNativeWindowSurfaceFactory(int displayWidth, int displayHeight, bool critical,
+ bool async);
+ void expectFramebufferUsageSet(int width, int height, int grallocUsage);
+ void expectHwcHotplugCalls(hwc2_display_t displayId, int displayWidth, int displayHeight);
+
+ // --------------------------------------------------------------------
+ // Call expectation helpers
+
+ void expectRESurfaceCreationCalls();
+ void expectPhysicalDisplayDeviceCreationCalls(hwc2_display_t displayId, int displayWidth,
+ int displayHeight, bool critical, bool async);
+
+ // --------------------------------------------------------------------
+ // Postcondition helpers
+
+ bool hasTransactionFlagSet(int flag);
+ bool hasDisplayDevice(sp<IBinder> displayToken);
+ sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
+ bool hasCurrentDisplayState(sp<IBinder> displayToken);
+ const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
+ bool hasDrawingDisplayState(sp<IBinder> displayToken);
+ const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
+
+ // --------------------------------------------------------------------
+ // Test instances
std::unordered_set<HWC2::Capability> mCapabilities;
TestableSurfaceFlinger mFlinger;
mock::EventThread* mEventThread = new mock::EventThread();
+ mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
// These mocks are created by the test, but are destroyed by SurfaceFlinger
// by virtue of being stored into a std::unique_ptr. However we still need
// to keep a reference to them for use in setting up call expectations.
RE::mock::RenderEngine* mRenderEngine = new RE::mock::RenderEngine();
Hwc2::mock::Composer* mComposer = new Hwc2::mock::Composer();
+ mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
+ mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
// These mocks are created only when expected to be created via a factory.
sp<mock::GraphicBufferConsumer> mConsumer;
sp<mock::GraphicBufferProducer> mProducer;
- std::unique_ptr<HWC2Display> mDisplay;
+ mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
+ sp<mock::NativeWindow> mNativeWindow;
+ RE::mock::Surface* mRenderSurface = nullptr;
+ std::vector<std::unique_ptr<HWC2Display>> mFakeHwcDisplays;
};
DisplayTransactionTest::DisplayTransactionTest() {
@@ -85,8 +170,16 @@
ADD_FAILURE() << "Unexpected request to create a buffer queue.";
});
+ mFlinger.setCreateNativeWindowSurface([](auto) {
+ ADD_FAILURE() << "Unexpected request to create a native window surface.";
+ return nullptr;
+ });
+
+ mFlinger.mutableEventControlThread().reset(mEventControlThread);
mFlinger.mutableEventThread().reset(mEventThread);
+ mFlinger.mutableEventQueue().reset(mMessageQueue);
mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
+ mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
setupComposer(0);
}
@@ -106,26 +199,49 @@
Mock::VerifyAndClear(mComposer);
}
-void DisplayTransactionTest::setupPrimaryDisplay(int width, int height) {
- mDisplay = std::make_unique<HWC2Display>(*mComposer, mCapabilities, 0,
- HWC2::DisplayType::Physical);
+void DisplayTransactionTest::setupFakeHwcDisplay(hwc2_display_t displayId,
+ DisplayDevice::DisplayType type, int width,
+ int height) {
+ auto display = std::make_unique<HWC2Display>(*mComposer, mCapabilities, displayId,
+ HWC2::DisplayType::Physical);
+ display->mutableIsConnected() = true;
+ display->mutableConfigs().emplace(DEFAULT_CONFIG_ID,
+ HWC2::Display::Config::Builder(*display, DEFAULT_CONFIG_ID)
+ .setWidth(width)
+ .setHeight(height)
+ .setVsyncPeriod(DEFAULT_REFRESH_RATE)
+ .setDpiX(DEFAULT_DPI)
+ .setDpiY(DEFAULT_DPI)
+ .build());
- mDisplay->mutableIsConnected() = true;
- mDisplay->mutableConfigs().emplace(0,
- HWC2::Display::Config::Builder(*mDisplay, 0)
- .setWidth(width)
- .setHeight(height)
- .setVsyncPeriod(DEFAULT_REFRESH_RATE)
- .setDpiX(DEFAULT_DPI)
- .setDpiY(DEFAULT_DPI)
- .build());
+ mFlinger.mutableHwcDisplayData()[type].reset();
+ mFlinger.mutableHwcDisplayData()[type].hwcDisplay = display.get();
+ mFlinger.mutableHwcDisplaySlots().emplace(displayId, type);
- mFlinger.mutableHwcDisplayData()[DisplayDevice::DISPLAY_PRIMARY].reset();
- mFlinger.mutableHwcDisplayData()[DisplayDevice::DISPLAY_PRIMARY].hwcDisplay = mDisplay.get();
- mFlinger.mutableHwcDisplaySlots().emplace(0, DisplayDevice::DISPLAY_PRIMARY);
+ mFakeHwcDisplays.push_back(std::move(display));
}
-void DisplayTransactionTest::expectFramebufferQueuePairCreation(int width, int height) {
+sp<BBinder> DisplayTransactionTest::setupFakeExistingPhysicalDisplay(
+ hwc2_display_t displayId, DisplayDevice::DisplayType type) {
+ setupFakeHwcDisplay(displayId, type, 0, 0);
+
+ sp<BBinder> displayToken = new BBinder();
+ mFlinger.mutableBuiltinDisplays()[type] = displayToken;
+ mFlinger.mutableDisplays()
+ .add(displayToken,
+ FakeDisplayDeviceFactory(mFlinger, displayToken, type, type).build());
+
+ DisplayDeviceState state(type, true);
+ mFlinger.mutableCurrentState().displays.add(displayToken, state);
+ mFlinger.mutableDrawingState().displays.add(displayToken, state);
+
+ return displayToken;
+}
+
+void DisplayTransactionTest::setupFakeBufferQueueFactory() {
+ // This setup is only expected once per test.
+ ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
+
mConsumer = new mock::GraphicBufferConsumer();
mProducer = new mock::GraphicBufferProducer();
@@ -133,61 +249,187 @@
*outProducer = mProducer;
*outConsumer = mConsumer;
});
+}
+void DisplayTransactionTest::setupFakeNativeWindowSurfaceFactory(int displayWidth,
+ int displayHeight, bool critical,
+ bool async) {
+ // This setup is only expected once per test.
+ ASSERT_TRUE(mNativeWindowSurface == nullptr);
+
+ mNativeWindowSurface = new mock::NativeWindowSurface();
+ mNativeWindow = new mock::NativeWindow();
+
+ mFlinger.setCreateNativeWindowSurface(
+ [this](auto) { return std::unique_ptr<NativeWindowSurface>(mNativeWindowSurface); });
+
+ EXPECT_CALL(*mNativeWindowSurface, getNativeWindow()).WillOnce(Return(mNativeWindow));
+
+ EXPECT_CALL(*mNativeWindow, perform(19)).Times(1);
+
+ EXPECT_CALL(*mRenderSurface, setAsync(async)).Times(1);
+ EXPECT_CALL(*mRenderSurface, setCritical(critical)).Times(1);
+ EXPECT_CALL(*mRenderSurface, setNativeWindow(mNativeWindow.get())).Times(1);
+ EXPECT_CALL(*mRenderSurface, queryWidth()).WillOnce(Return(displayWidth));
+ EXPECT_CALL(*mRenderSurface, queryHeight()).WillOnce(Return(displayHeight));
+}
+
+void DisplayTransactionTest::expectFramebufferUsageSet(int width, int height, int grallocUsage) {
EXPECT_CALL(*mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
- EXPECT_CALL(*mConsumer,
- setConsumerUsageBits(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
- GRALLOC_USAGE_HW_FB))
- .WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*mConsumer, setConsumerUsageBits(grallocUsage)).WillRepeatedly(Return(NO_ERROR));
EXPECT_CALL(*mConsumer, setDefaultBufferSize(width, height)).WillRepeatedly(Return(NO_ERROR));
EXPECT_CALL(*mConsumer, setMaxAcquiredBufferCount(_)).WillRepeatedly(Return(NO_ERROR));
EXPECT_CALL(*mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
}
-TEST_F(DisplayTransactionTest, processDisplayChangesLockedProcessesPrimaryDisplayConnected) {
- using android::hardware::graphics::common::V1_0::ColorMode;
+void DisplayTransactionTest::expectHwcHotplugCalls(hwc2_display_t displayId, int displayWidth,
+ int displayHeight) {
+ EXPECT_CALL(*mComposer, getDisplayType(displayId, _))
+ .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayType::PHYSICAL),
+ Return(Error::NONE)));
+ EXPECT_CALL(*mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*mComposer, getDisplayConfigs(_, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{0}), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::WIDTH, _))
+ .WillOnce(DoAll(SetArgPointee<3>(displayWidth), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer,
+ getDisplayAttribute(displayId, 0, IComposerClient::Attribute::HEIGHT, _))
+ .WillOnce(DoAll(SetArgPointee<3>(displayHeight), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer,
+ getDisplayAttribute(displayId, 0, IComposerClient::Attribute::VSYNC_PERIOD, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::DPI_X, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer, getDisplayAttribute(displayId, 0, IComposerClient::Attribute::DPI_Y, _))
+ .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
+}
- setupPrimaryDisplay(1920, 1080);
+void DisplayTransactionTest::expectRESurfaceCreationCalls() {
+ // This setup is only expected once per test.
+ ASSERT_TRUE(mRenderSurface == nullptr);
- sp<BBinder> token = new BBinder();
- mFlinger.mutableCurrentState().displays.add(token, {DisplayDevice::DISPLAY_PRIMARY, true});
+ mRenderSurface = new RE::mock::Surface();
+ EXPECT_CALL(*mRenderEngine, createSurface())
+ .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(mRenderSurface))));
+}
- EXPECT_CALL(*mComposer, getActiveConfig(DisplayDevice::DISPLAY_PRIMARY, _))
- .WillOnce(DoAll(SetArgPointee<1>(0), Return(Error::NONE)));
- EXPECT_CALL(*mComposer, getColorModes(DisplayDevice::DISPLAY_PRIMARY, _)).Times(0);
- EXPECT_CALL(*mComposer, getHdrCapabilities(DisplayDevice::DISPLAY_PRIMARY, _, _, _, _))
+void DisplayTransactionTest::expectPhysicalDisplayDeviceCreationCalls(hwc2_display_t displayId,
+ int displayWidth,
+ int displayHeight,
+ bool critical, bool async) {
+ EXPECT_CALL(*mComposer, getActiveConfig(displayId, _))
+ .WillOnce(DoAll(SetArgPointee<1>(DEFAULT_CONFIG_ID), Return(Error::NONE)));
+ EXPECT_CALL(*mComposer, getColorModes(displayId, _)).Times(0);
+ EXPECT_CALL(*mComposer, getHdrCapabilities(displayId, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
- expectFramebufferQueuePairCreation(1920, 1080);
+ setupFakeBufferQueueFactory();
+ expectFramebufferUsageSet(displayWidth, displayHeight,
+ GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
+ GRALLOC_USAGE_HW_FB);
- auto reSurface = new RE::mock::Surface();
- EXPECT_CALL(*mRenderEngine, createSurface())
- .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(reSurface))));
- EXPECT_CALL(*reSurface, setAsync(false)).Times(1);
- EXPECT_CALL(*reSurface, setCritical(true)).Times(1);
- EXPECT_CALL(*reSurface, setNativeWindow(_)).Times(1);
- EXPECT_CALL(*reSurface, queryWidth()).WillOnce(Return(1920));
- EXPECT_CALL(*reSurface, queryHeight()).WillOnce(Return(1080));
+ setupFakeNativeWindowSurfaceFactory(displayWidth, displayHeight, critical, async);
+}
+
+bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
+ return mFlinger.mutableTransactionFlags() & flag;
+}
+
+bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
+ return mFlinger.mutableDisplays().indexOfKey(displayToken) >= 0;
+}
+
+sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
+ return mFlinger.mutableDisplays().valueFor(displayToken);
+}
+
+bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
+ return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
+}
+
+const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
+ return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
+}
+
+bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
+ return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
+}
+
+const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
+ return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
+}
+
+/* ------------------------------------------------------------------------
+ * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
+ */
+
+TEST_F(DisplayTransactionTest, handleTransactionLockedProcessesHotplugConnectPrimary) {
+ constexpr hwc2_display_t externalDisplayId = 102;
+ constexpr hwc2_display_t displayId = 123;
+ constexpr int displayWidth = 1920;
+ constexpr int displayHeight = 1080;
+
+ // --------------------------------------------------------------------
+ // Preconditions
+
+ // An external display may already be set up
+ setupFakeHwcDisplay(externalDisplayId, DisplayDevice::DISPLAY_EXTERNAL, 3840, 2160);
+
+ // A hotplug connect comes in for a new display
+ mFlinger.mutablePendingHotplugEvents().emplace_back(
+ HotplugEvent{displayId, HWC2::Connection::Connected});
+
+ // --------------------------------------------------------------------
+ // Call Expectations
+
+ EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
+ expectHwcHotplugCalls(displayId, displayWidth, displayHeight);
+ expectRESurfaceCreationCalls();
+ expectPhysicalDisplayDeviceCreationCalls(displayId, displayWidth, displayHeight, true, false);
+
+ EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
EXPECT_CALL(*mEventThread, onHotplugReceived(DisplayDevice::DISPLAY_PRIMARY, true)).Times(1);
- mFlinger.processDisplayChangesLocked();
+ // --------------------------------------------------------------------
+ // Invocation
- ASSERT_TRUE(mFlinger.mutableDisplays().indexOfKey(token) >= 0);
+ mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
- const auto& device = mFlinger.mutableDisplays().valueFor(token);
- ASSERT_TRUE(device.get());
+ // --------------------------------------------------------------------
+ // Postconditions
+
+ // HWComposer should have an entry for the display
+ EXPECT_TRUE(mFlinger.mutableHwcDisplaySlots().count(displayId) == 1);
+
+ // The display should have set up as a primary built-in display.
+ auto displayToken = mFlinger.mutableBuiltinDisplays()[DisplayDevice::DISPLAY_PRIMARY];
+ ASSERT_TRUE(displayToken != nullptr);
+
+ // The display device should have been set up in the list of displays.
+ ASSERT_TRUE(hasDisplayDevice(displayToken));
+ const auto& device = getDisplayDevice(displayToken);
EXPECT_TRUE(device->isSecure());
EXPECT_TRUE(device->isPrimary());
- ssize_t i = mFlinger.mutableDrawingState().displays.indexOfKey(token);
- ASSERT_GE(0, i);
- const auto& draw = mFlinger.mutableDrawingState().displays[i];
+ // The display should have been set up in the current display state
+ ASSERT_TRUE(hasCurrentDisplayState(displayToken));
+ const auto& current = getCurrentDisplayState(displayToken);
+ EXPECT_EQ(DisplayDevice::DISPLAY_PRIMARY, current.type);
+
+ // The display should have been set up in the drawing display state
+ ASSERT_TRUE(hasDrawingDisplayState(displayToken));
+ const auto& draw = getDrawingDisplayState(displayToken);
EXPECT_EQ(DisplayDevice::DISPLAY_PRIMARY, draw.type);
- EXPECT_CALL(*mConsumer, consumerDisconnect()).Times(1);
+ // --------------------------------------------------------------------
+ // Cleanup conditions
+
+ EXPECT_CALL(*mComposer, setVsyncEnabled(displayId, IComposerClient::Vsync::DISABLE))
+ .WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp b/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp
new file mode 100644
index 0000000..0314568
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 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 "MockNativeWindowSurface.h"
+
+namespace android {
+namespace mock {
+
+// Explicit default instantiation is recommended.
+NativeWindowSurface::NativeWindowSurface() = default;
+NativeWindowSurface::~NativeWindowSurface() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.h b/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.h
new file mode 100644
index 0000000..88d1a9f
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockNativeWindowSurface.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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
+
+#include <gmock/gmock.h>
+
+#include <system/window.h> // for ANativeWindow
+
+#include "SurfaceFlinger.h" // for base NativeWindowSurface
+
+namespace android {
+namespace mock {
+
+class NativeWindowSurface : public android::NativeWindowSurface {
+public:
+ NativeWindowSurface();
+ ~NativeWindowSurface();
+
+ MOCK_CONST_METHOD0(getNativeWindow, sp<ANativeWindow>());
+ MOCK_METHOD0(preallocateBuffers, void());
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 3e58eb8..2dd8e5f 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -45,26 +45,40 @@
}
using CreateBufferQueueFunction = SurfaceFlinger::CreateBufferQueueFunction;
-
void setCreateBufferQueueFunction(CreateBufferQueueFunction f) {
mFlinger->mCreateBufferQueue = f;
}
+ using CreateNativeWindowSurfaceFunction = SurfaceFlinger::CreateNativeWindowSurfaceFunction;
+ void setCreateNativeWindowSurface(CreateNativeWindowSurfaceFunction f) {
+ mFlinger->mCreateNativeWindowSurface = f;
+ }
+
+ using HotplugEvent = SurfaceFlinger::HotplugEvent;
+
/* ------------------------------------------------------------------------
* Forwarding for functions being tested
*/
- auto processDisplayChangesLocked() { return mFlinger->processDisplayChangesLocked(); }
+
+ auto handleTransactionLocked(uint32_t transactionFlags) {
+ return mFlinger->handleTransactionLocked(transactionFlags);
+ }
/* ------------------------------------------------------------------------
* Read-write access to private data to set up preconditions and assert
* post-conditions.
*/
+
auto& mutableBuiltinDisplays() { return mFlinger->mBuiltinDisplays; }
- auto& mutableDisplays() { return mFlinger->mDisplays; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }
+ auto& mutableDisplays() { return mFlinger->mDisplays; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
- auto& mutableEventThread() { return mFlinger->mEventThread; }
+ auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
auto& mutableEventQueue() { return mFlinger->mEventQueue; }
+ auto& mutableEventThread() { return mFlinger->mEventThread; }
+ auto& mutableInterceptor() { return mFlinger->mInterceptor; }
+ auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
+ auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutableHwcDisplayData() { return mFlinger->getBE().mHwc->mDisplayData; }
auto& mutableHwcDisplaySlots() { return mFlinger->getBE().mHwc->mHwcDisplaySlots; }
@@ -75,7 +89,10 @@
// still be referenced by something despite our best efforts to destroy
// it after each test is done.
mutableDisplays().clear();
+ mutableEventControlThread().reset();
+ mutableEventQueue().reset();
mutableEventThread().reset();
+ mutableInterceptor().reset();
mFlinger->getBE().mHwc.reset();
mFlinger->getBE().mRenderEngine.reset();
}
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
index 313c022..11ffc3f 100644
--- a/services/vr/hardware_composer/impl/vr_hwc.cpp
+++ b/services/vr/hardware_composer/impl/vr_hwc.cpp
@@ -868,7 +868,7 @@
Error status = Error::NONE;
sp<VrComposerClient> client;
- if (client_ == nullptr) {
+ if (!client_.promote().get()) {
client = new VrComposerClient(*this);
} else {
ALOGE("Already have a client");