diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 178 |
1 files changed, 97 insertions, 81 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 62d47e1d6e..c1d86e885b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -61,8 +61,10 @@ #include <renderengine/RenderEngine.h> #include <ui/ColorSpace.h> #include <ui/DebugUtils.h> +#include <ui/DisplayConfig.h> #include <ui/DisplayInfo.h> #include <ui/DisplayStatInfo.h> +#include <ui/DisplayState.h> #include <ui/GraphicBufferAllocator.h> #include <ui/PixelFormat.h> #include <ui/UiConfig.h> @@ -115,6 +117,7 @@ #include "android-base/parseint.h" #include "android-base/stringprintf.h" +#include <android/configuration.h> #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h> #include <android/hardware/configstore/1.1/types.h> @@ -182,6 +185,19 @@ private: bool mLocked; }; +// TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity. +constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV / 160.f; + +float getDensityFromProperty(const char* property, bool required) { + char value[PROPERTY_VALUE_MAX]; + const float density = property_get(property, value, nullptr) > 0 ? std::atof(value) : 0.f; + if (!density && required) { + ALOGE("%s must be defined as a build property", property); + return FALLBACK_DENSITY; + } + return density / 160.f; +} + // Currently we only support V0_SRGB and DISPLAY_P3 as composition preference. bool validateCompositionDataspace(Dataspace dataspace) { return dataspace == Dataspace::V0_SRGB || dataspace == Dataspace::DISPLAY_P3; @@ -249,7 +265,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mFrameTracer(std::make_unique<FrameTracer>()), mEventQueue(mFactory.createMessageQueue()), mCompositionEngine(mFactory.createCompositionEngine()), - mPendingSyncInputWindows(false) {} + mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), + mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) {} SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) { ALOGI("SurfaceFlinger is starting"); @@ -734,8 +751,56 @@ status_t SurfaceFlinger::getSupportedFrameTimestamps( return NO_ERROR; } +status_t SurfaceFlinger::getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState* state) { + if (!displayToken || !state) { + return BAD_VALUE; + } + + Mutex::Autolock lock(mStateLock); + + const auto display = getDisplayDeviceLocked(displayToken); + if (!display) { + return NAME_NOT_FOUND; + } + + state->layerStack = display->getLayerStack(); + state->orientation = display->getOrientation(); + + const Rect viewport = display->getViewport(); + state->viewport = viewport.isValid() ? viewport.getSize() : display->getSize(); + + return NO_ERROR; +} + +status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& displayToken, DisplayInfo* info) { + if (!displayToken || !info) { + return BAD_VALUE; + } + + Mutex::Autolock lock(mStateLock); + + const auto display = getDisplayDeviceLocked(displayToken); + if (!display) { + return NAME_NOT_FOUND; + } + + if (display->isVirtual()) { + return INVALID_OPERATION; + } + + if (mEmulatedDisplayDensity) { + info->density = mEmulatedDisplayDensity; + } else { + info->density = display->isPrimary() ? mInternalDisplayDensity : FALLBACK_DENSITY; + } + + info->secure = display->isSecure(); + + return NO_ERROR; +} + status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, - Vector<DisplayInfo>* configs) { + Vector<DisplayConfig>* configs) { if (!displayToken || !configs) { return BAD_VALUE; } @@ -747,78 +812,42 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, return NAME_NOT_FOUND; } - // TODO: Not sure if display density should handled by SF any longer - class Density { - static float getDensityFromProperty(char const* propName) { - char property[PROPERTY_VALUE_MAX]; - float density = 0.0f; - if (property_get(propName, property, nullptr) > 0) { - density = strtof(property, nullptr); - } - return density; - } - public: - static float getEmuDensity() { - return getDensityFromProperty("qemu.sf.lcd_density"); } - static float getBuildDensity() { - return getDensityFromProperty("ro.sf.lcd_density"); } - }; + const bool isInternal = (displayId == getInternalDisplayIdLocked()); configs->clear(); for (const auto& hwConfig : getHwComposer().getConfigs(*displayId)) { - DisplayInfo info = DisplayInfo(); - - float xdpi = hwConfig->getDpiX(); - float ydpi = hwConfig->getDpiY(); - - info.w = hwConfig->getWidth(); - info.h = hwConfig->getHeight(); - // Default display viewport to display width and height - info.viewportW = info.w; - info.viewportH = info.h; - - if (displayId == getInternalDisplayIdLocked()) { - // The density of the device is provided by a build property - float density = Density::getBuildDensity() / 160.0f; - if (density == 0) { - // the build doesn't provide a density -- this is wrong! - // use xdpi instead - ALOGE("ro.sf.lcd_density must be defined as a build property"); - density = xdpi / 160.0f; - } - if (Density::getEmuDensity()) { - // if "qemu.sf.lcd_density" is specified, it overrides everything - xdpi = ydpi = density = Density::getEmuDensity(); - density /= 160.0f; - } - info.density = density; + DisplayConfig config; - const auto display = getDefaultDisplayDeviceLocked(); - info.orientation = display->getOrientation(); + auto width = hwConfig->getWidth(); + auto height = hwConfig->getHeight(); - // This is for screenrecord - const Rect viewport = display->getViewport(); - if (viewport.isValid()) { - info.viewportW = uint32_t(viewport.getWidth()); - info.viewportH = uint32_t(viewport.getHeight()); - } - info.layerStack = display->getLayerStack(); - } else { - // TODO: where should this value come from? - static const int TV_DENSITY = 213; - info.density = TV_DENSITY / 160.0f; + auto xDpi = hwConfig->getDpiX(); + auto yDpi = hwConfig->getDpiY(); + + if (isInternal && + (internalDisplayOrientation == ui::ROTATION_90 || + internalDisplayOrientation == ui::ROTATION_270)) { + std::swap(width, height); + std::swap(xDpi, yDpi); + } - const auto display = getDisplayDeviceLocked(displayToken); - info.layerStack = display->getLayerStack(); + config.resolution = ui::Size(width, height); + + if (mEmulatedDisplayDensity) { + config.xDpi = mEmulatedDisplayDensity; + config.yDpi = mEmulatedDisplayDensity; + } else { + config.xDpi = xDpi; + config.yDpi = yDpi; } - info.xdpi = xdpi; - info.ydpi = ydpi; - info.fps = 1e9 / hwConfig->getVsyncPeriod(); + const nsecs_t period = hwConfig->getVsyncPeriod(); + config.refreshRate = 1e9f / period; - const auto offset = mPhaseConfiguration->getOffsetsForRefreshRate(info.fps); - info.appVsyncOffset = offset.late.app; + const auto offsets = mPhaseConfiguration->getOffsetsForRefreshRate(config.refreshRate); + config.appVsyncOffset = offsets.late.app; + config.sfVsyncOffset = offsets.late.sf; // This is how far in advance a buffer must be queued for // presentation at a given time. If you want a buffer to appear @@ -832,18 +861,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, // // We add an additional 1ms to allow for processing time and // differences between the ideal and actual refresh rate. - info.presentationDeadline = hwConfig->getVsyncPeriod() - offset.late.sf + 1000000; + config.presentationDeadline = period - config.sfVsyncOffset + 1000000; - // All non-virtual displays are currently considered secure. - info.secure = true; - - if (displayId == getInternalDisplayIdLocked() && - (internalDisplayOrientation == ui::ROTATION_90 || - internalDisplayOrientation == ui::ROTATION_270)) { - std::swap(info.w, info.h); - } - - configs->push_back(info); + configs->push_back(config); } return NO_ERROR; @@ -4614,7 +4634,9 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case GET_PHYSICAL_DISPLAY_TOKEN: case GET_DISPLAY_COLOR_MODES: case GET_DISPLAY_NATIVE_PRIMARIES: + case GET_DISPLAY_INFO: case GET_DISPLAY_CONFIGS: + case GET_DISPLAY_STATE: case GET_DISPLAY_STATS: case GET_SUPPORTED_FRAME_TIMESTAMPS: // Calling setTransactionState is safe, because you need to have been @@ -4644,12 +4666,6 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { } return OK; } - // The following codes are deprecated and should never be allowed to access SF. - case CONNECT_DISPLAY_UNUSED: - case CREATE_GRAPHIC_BUFFER_ALLOC_UNUSED: { - ALOGE("Attempting to access SurfaceFlinger with unused code: %u", code); - return PERMISSION_DENIED; - } case CAPTURE_SCREEN_BY_ID: { IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); |