if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this] (bool requestDisplay) {
- ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
- mVrFlingerRequestsDisplay = requestDisplay;
- signalTransaction();
+ // This callback is called from the vr flinger dispatch thread. We
+ // need to call signalTransaction(), which requires holding
+ // mStateLock when we're not on the main thread. Acquiring
+ // mStateLock from the vr flinger dispatch thread might trigger a
+ // deadlock in surface flinger (see b/66916578), so post a message
+ // to be handled on the main thread instead.
+ sp<LambdaMessage> message = new LambdaMessage([=]() {
+ ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
+ mVrFlingerRequestsDisplay = requestDisplay;
+ signalTransaction();
+ });
+ postMessageAsync(message);
};
mVrFlinger = dvr::VrFlinger::Create(mHwc->getComposer(),
vrFlingerRequestDisplayCallback);
property_get("persist.sys.sf.color_saturation", value, "1.0");
mSaturation = atof(value);
ALOGV("Saturation is set to %.2f", mSaturation);
+
+ property_get("persist.sys.sf.native_mode", value, "0");
+ mForceNativeColorMode = atoi(value) == 1;
+ if (mForceNativeColorMode) {
+ ALOGV("Forcing native color mode");
+ }
}
void SurfaceFlinger::startBootAnim() {
FrameEvent::DEQUEUE_READY,
FrameEvent::RELEASE,
};
+ ConditionalLock _l(mStateLock,
+ std::this_thread::get_id() != mMainThreadId);
if (!getHwComposer().hasCapability(
HWC2::Capability::PresentFenceIsNotReliable)) {
outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
public:
static int getEmuDensity() {
return getDensityFromProperty("qemu.sf.lcd_density"); }
- static int getBuildDensity() {
- return getDensityFromProperty("ro.sf.lcd_density"); }
+ static int getBuildDensity(const DisplayInfo& info) {
+ static int density = getDensityFromProperty("ro.sf.lcd_density");
+#if defined(__i386__) || defined(__x86_64__)
+ if (density == 0) {
+ uint32_t area = info.w * info.h;
+ if (area <= 800 * 480) {
+ density = 120;
+ } else if (area <= 1024 * 600) {
+ density = 130;
+ } else if (area < 1024 * 768) {
+ density = 140;
+ } else if (area < 1920 * 1080) {
+ density = 160;
+ } else {
+ density = 240;
+ }
+ ALOGI("auto set density to %d", density);
+ }
+#endif
+ return density;
+ }
};
configs->clear();
+ ConditionalLock _l(mStateLock,
+ std::this_thread::get_id() != mMainThreadId);
for (const auto& hwConfig : getHwComposer().getConfigs(type)) {
DisplayInfo info = DisplayInfo();
float xdpi = hwConfig->getDpiX();
float ydpi = hwConfig->getDpiY();
+ info.w = hwConfig->getWidth();
+ info.h = hwConfig->getHeight();
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// The density of the device is provided by a build property
- float density = Density::getBuildDensity() / 160.0f;
+ float density = Density::getBuildDensity(info) / 160.0f;
if (density == 0) {
// the build doesn't provide a density -- this is wrong!
// use xdpi instead
info.density = density;
// TODO: this needs to go away (currently needed only by webkit)
- sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
info.orientation = hw->getOrientation();
} else {
// TODO: where should this value come from?
info.orientation = 0;
}
- info.w = hwConfig->getWidth();
- info.h = hwConfig->getHeight();
info.xdpi = xdpi;
info.ydpi = ydpi;
info.fps = 1e9 / hwConfig->getVsyncPeriod();
return type;
}
- std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
+ std::vector<android_color_mode_t> modes;
+ {
+ ConditionalLock _l(mStateLock,
+ std::this_thread::get_id() != mMainThreadId);
+ modes = getHwComposer().getColorModes(type);
+ }
outColorModes->clear();
std::copy(modes.cbegin(), modes.cend(), std::back_inserter(*outColorModes));
mEventQueue.waitMessage();
}
+#ifdef CONSOLE_MANAGER
+void SurfaceFlinger::screenReleased(const sp<IBinder>& display) {
+ // this may be called by a signal handler, we can't do too much in here
+ setPowerMode(display, HWC_POWER_MODE_OFF);
+ signalLayerUpdate();
+}
+
+void SurfaceFlinger::screenAcquired(const sp<IBinder>& display) {
+ // this may be called by a signal handler, we can't do too much in here
+ setPowerMode(display, HWC_POWER_MODE_NORMAL);
+ signalLayerUpdate();
+}
+#endif
+
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}
break;
}
}
+ bool useWideColorMode = hasWideColorModes && hasWideColorDisplay && !mForceNativeColorMode;
sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
token, fbs, producer, mRenderEngine->getEGLConfig(),
- hasWideColorModes && hasWideColorDisplay);
+ useWideColorMode);
mDisplays.add(token, hw);
android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
- if (hasWideColorModes && hasWideColorDisplay) {
+ if (useWideColorMode) {
defaultColorMode = HAL_COLOR_MODE_SRGB;
}
setActiveColorModeInternal(hw, defaultColorMode);
if (sequenceId != mComposerSequenceId) {
return;
}
- repaintEverything();
+ repaintEverythingLocked();
}
void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
// pickColorMode translates a given dataspace into the best available color mode.
// Currently only support sRGB and Display-P3.
android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const {
+ if (mForceNativeColorMode) {
+ return HAL_COLOR_MODE_NATIVE;
+ }
+
switch (dataSpace) {
// treat Unknown as regular SRGB buffer, since that's what the rest of the
// system expects.
ALOGV("hasClientComposition");
#ifdef USE_HWC2
- mRenderEngine->setWideColor(displayDevice->getWideColorSupport());
- mRenderEngine->setColorMode(displayDevice->getActiveColorMode());
+ mRenderEngine->setWideColor(
+ displayDevice->getWideColorSupport() && !mForceNativeColorMode);
+ mRenderEngine->setColorMode(mForceNativeColorMode ?
+ HAL_COLOR_MODE_NATIVE : displayDevice->getActiveColorMode());
#endif
if (!displayDevice->makeCurrent(mEGLDisplay, mEGLContext)) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
mVisibleRegionsDirty = true;
mHasPoweredOff = true;
- repaintEverything();
+ repaintEverythingLocked();
struct sched_param param = {0};
param.sched_priority = 1;
void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
+ result.appendFormat("forceNativeColorMode: %d\n", mForceNativeColorMode);
// TODO: print out if wide-color mode is active or not
return NO_ERROR;
}
case 1005:{ // force transaction
+ Mutex::Autolock _l(mStateLock);
setTransactionFlags(
eTransactionNeeded|
eDisplayTransactionNeeded|
repaintEverything();
return NO_ERROR;
}
+ case 1023: { // Set native mode
+ mForceNativeColorMode = data.readInt32() == 1;
+
+ invalidateHwcGeometry();
+ repaintEverything();
+ return NO_ERROR;
+ }
+ case 1024: { // Is wide color gamut rendering/color management supported?
+ reply->writeBool(hasWideColorDisplay);
+ return NO_ERROR;
+ }
}
}
return err;
}
-void SurfaceFlinger::repaintEverything() {
+void SurfaceFlinger::repaintEverythingLocked() {
android_atomic_or(1, &mRepaintEverything);
signalTransaction();
}
+void SurfaceFlinger::repaintEverything() {
+ ConditionalLock _l(mStateLock,
+ std::this_thread::get_id() != mMainThreadId);
+ repaintEverythingLocked();
+}
+
// Checks that the requested width and height are valid and updates them to the display dimensions
// if they are set to 0
static status_t updateDimensionsLocked(const sp<const DisplayDevice>& displayDevice,
WindowDisconnector disconnector(window, NATIVE_WINDOW_API_EGL);
ANativeWindowBuffer* buffer = nullptr;
- result = getWindowBuffer(window, reqWidth, reqHeight, hasWideColorDisplay,
- getRenderEngine().usesWideColor(), &buffer);
+ result = getWindowBuffer(window, reqWidth, reqHeight,
+ hasWideColorDisplay && !mForceNativeColorMode,
+ getRenderEngine().usesWideColor(), &buffer);
if (result != NO_ERROR) {
return result;
}
}
#ifdef USE_HWC2
- engine.setWideColor(hw->getWideColorSupport());
- engine.setColorMode(hw->getActiveColorMode());
+ engine.setWideColor(hw->getWideColorSupport() && !mForceNativeColorMode);
+ engine.setColorMode(mForceNativeColorMode ? HAL_COLOR_MODE_NATIVE : hw->getActiveColorMode());
#endif
// make sure to clear all GL error flags