diff options
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 70 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 9 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 155 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 21 |
4 files changed, 157 insertions, 98 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 92d5e21f34..fe0b30ba35 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -57,9 +57,6 @@ using namespace android; 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 @@ DisplayDevice::DisplayDevice( 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 737971f83d..fbb0d462f3 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -77,9 +77,14 @@ public: 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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cdf126e9e2..b99e17f16f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -154,6 +154,32 @@ bool useTrebleTestingOverride() { 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 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) 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"); @@ -2080,7 +2107,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) } 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 @@ -2149,6 +2176,84 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { 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 @@ -2271,50 +2376,10 @@ void SurfaceFlinger::processDisplayChangesLocked() { } 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); } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 7d15622d4f..ec9633d057 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -118,6 +118,19 @@ enum { 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: @@ -646,6 +659,10 @@ private: */ 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(); @@ -837,6 +854,10 @@ private: bool /* consumerIsSurfaceFlinger */)>; CreateBufferQueueFunction mCreateBufferQueue; + using CreateNativeWindowSurfaceFunction = + std::function<std::unique_ptr<NativeWindowSurface>(const sp<IGraphicBufferProducer>&)>; + CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface; + SurfaceFlingerBE mBE; }; }; // namespace android |