diff options
13 files changed, 136 insertions, 114 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 89779afa75..73184db13e 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \ DisplayHardware/ComposerHal.cpp \ DisplayHardware/FramebufferSurface.cpp \ DisplayHardware/HWC2.cpp \ + DisplayHardware/HWComposerBufferCache.cpp \ DisplayHardware/PowerHAL.cpp \ DisplayHardware/VirtualDisplaySurface.cpp \ Effects/Daltonizer.cpp \ diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index d384bb1b0a..92a7794434 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -137,7 +137,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& status_t err = acquireBufferLocked(&item, 0); if (err == BufferQueue::NO_BUFFER_AVAILABLE) { #ifdef USE_HWC2 - mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, + mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer); #else outBuffer = mCurrentBuffer; @@ -178,7 +178,7 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence = item.mFence; #ifdef USE_HWC2 - mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, + mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer); outDataspace = item.mDataSpace; #else diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index 5eea6b6056..69a72d7ede 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -18,14 +18,13 @@ #define ANDROID_SF_FRAMEBUFFER_SURFACE_H #include "DisplaySurface.h" +#include "HWComposerBufferCache.h" #include <stdint.h> #include <sys/types.h> #include <gui/ConsumerBase.h> -#include <memory> - // --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- @@ -33,7 +32,6 @@ namespace android { class Rect; class String8; class HWComposer; -class HWComposerBufferCache; // --------------------------------------------------------------------------- @@ -96,8 +94,7 @@ private: HWComposer& mHwc; #ifdef USE_HWC2 - std::unique_ptr<HWComposerBufferCache> mHwcBufferCache = - std::make_unique<HWComposerBufferCache>(); + HWComposerBufferCache mHwcBufferCache; // Previous buffer to release after getting an updated retire fence bool mHasPendingRelease; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index e1138af15a..6644bd9fe3 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -925,41 +925,5 @@ void HWComposer::DisplayData::reset() { *this = DisplayData(); } -void HWComposerBufferCache::clear() -{ - mBuffers.clear(); -} - -void HWComposerBufferCache::getHwcBuffer(int slot, - const sp<GraphicBuffer>& buffer, - uint32_t* outSlot, sp<GraphicBuffer>* outBuffer) -{ -#ifdef BYPASS_IHWC - *outSlot = slot; - *outBuffer = buffer; -#else - if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) { - // default to slot 0 - slot = 0; - } - - if (static_cast<size_t>(slot) >= mBuffers.size()) { - mBuffers.resize(slot + 1); - } - - *outSlot = slot; - - if (mBuffers[slot] == buffer) { - // already cached in HWC, skip sending the buffer - *outBuffer = nullptr; - } else { - *outBuffer = buffer; - - // update cache - mBuffers[slot] = buffer; - } -#endif -} - // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 20cca391b0..117db4a424 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -26,8 +26,6 @@ #include <stdint.h> #include <sys/types.h> -#include <gui/BufferQueue.h> - #include <ui/Fence.h> #include <utils/BitSet.h> @@ -236,19 +234,6 @@ private: mutable std::atomic<bool> mDumpMayLockUp; }; -class HWComposerBufferCache { -public: - void clear(); - - void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, - uint32_t* outSlot, sp<GraphicBuffer>* outBuffer); - -private: - // a vector as we expect "slot" to be in the range of [0, 63] (that is, - // less than BufferQueue::NUM_BUFFER_SLOTS). - std::vector<sp<GraphicBuffer>> mBuffers; -}; - // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp new file mode 100644 index 0000000000..6b9122473f --- /dev/null +++ b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2017 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 "HWComposerBufferCache.h" + +#include <gui/BufferQueue.h> + +namespace android { + +HWComposerBufferCache::HWComposerBufferCache() +{ + mBuffers.reserve(BufferQueue::NUM_BUFFER_SLOTS); +} + +void HWComposerBufferCache::getHwcBuffer(int slot, + const sp<GraphicBuffer>& buffer, + uint32_t* outSlot, sp<GraphicBuffer>* outBuffer) +{ +#ifdef BYPASS_IHWC + *outSlot = slot; + *outBuffer = buffer; +#else + if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) { + // default to slot 0 + slot = 0; + } + + if (static_cast<size_t>(slot) >= mBuffers.size()) { + mBuffers.resize(slot + 1); + } + + *outSlot = slot; + + if (mBuffers[slot] == buffer) { + // already cached in HWC, skip sending the buffer + *outBuffer = nullptr; + } else { + *outBuffer = buffer; + + // update cache + mBuffers[slot] = buffer; + } +#endif +} + +} // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h new file mode 100644 index 0000000000..a008ca9117 --- /dev/null +++ b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef ANDROID_SF_HWCOMPOSERBUFFERCACHE_H +#define ANDROID_SF_HWCOMPOSERBUFFERCACHE_H + +#include <stdint.h> + +#include <utils/StrongPointer.h> + +#include <vector> + +namespace android { +// --------------------------------------------------------------------------- + +class GraphicBuffer; + +// With HIDLized hwcomposer HAL, the HAL can maintain a buffer cache for each +// HWC display and layer. When updating a display target or a layer buffer, +// we have the option to send the buffer handle over or to request the HAL to +// retrieve it from its cache. The latter is cheaper since it eliminates the +// overhead to transfer the handle over the trasport layer, and the overhead +// for the HAL to clone and retain the handle. +// +// To be able to find out whether a buffer is already in the HAL's cache, we +// use HWComposerBufferCache to mirror the cache in SF. +class HWComposerBufferCache { +public: + HWComposerBufferCache(); + + // Given a buffer queue slot and buffer, return the HWC cache slot and + // buffer to be sent to HWC. + // + // outBuffer is set to buffer when buffer is not in the HWC cache; + // otherwise, outBuffer is set to nullptr. + void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, + uint32_t* outSlot, sp<GraphicBuffer>* outBuffer); + +private: + // a vector as we expect "slot" to be in the range of [0, 63] (that is, + // less than BufferQueue::NUM_BUFFER_SLOTS). + std::vector<sp<GraphicBuffer>> mBuffers; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_SF_HWCOMPOSERBUFFERCACHE_H diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp index c5a4f99a4b..6f253ab9f3 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp @@ -224,7 +224,7 @@ status_t VirtualDisplaySurface::advanceFrame() { #ifdef USE_HWC2 uint32_t hwcSlot = 0; sp<GraphicBuffer> hwcBuffer; - mHwcBufferCache->getHwcBuffer(mFbProducerSlot, fbBuffer, + mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, &hwcSlot, &hwcBuffer); // TODO: Correctly propagate the dataspace from GL composition diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h index fb5fcc885c..ee2772ae4a 100644 --- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h +++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h @@ -18,18 +18,16 @@ #define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H #include "DisplaySurface.h" +#include "HWComposerBufferCache.h" #include <gui/ConsumerBase.h> #include <gui/IGraphicBufferProducer.h> -#include <memory> - // --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- class HWComposer; -class HWComposerBufferCache; class IProducerListener; /* This DisplaySurface implementation supports virtual displays, where GLES @@ -255,8 +253,7 @@ private: bool mMustRecompose; #ifdef USE_HWC2 - std::unique_ptr<HWComposerBufferCache> mHwcBufferCache = - std::make_unique<HWComposerBufferCache>(); + HWComposerBufferCache mHwcBufferCache; #endif }; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 7a4ace9405..51984b7d2a 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -276,16 +276,6 @@ void Layer::onFrameReplaced(const BufferItem& item) { } } -void Layer::onBuffersReleased() { -#ifdef USE_HWC2 - Mutex::Autolock lock(mHwcBufferCacheMutex); - - for (auto info : mHwcBufferCaches) { - info.second.clear(); - } -#endif -} - void Layer::onSidebandStreamChanged() { if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was false @@ -780,7 +770,8 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcLayer = mHwcLayers[hwcId].layer; + auto& hwcInfo = 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(), @@ -809,7 +800,7 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { } // Client layers - if (mHwcLayers[hwcId].forceClientComposition || + if (hwcInfo.forceClientComposition || (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { ALOGV("[%s] Requesting Client composition", mName.string()); setCompositionType(hwcId, HWC2::Composition::Client); @@ -858,11 +849,8 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { uint32_t hwcSlot = 0; buffer_handle_t hwcHandle = nullptr; { - Mutex::Autolock lock(mHwcBufferCacheMutex); - - auto& hwcBufferCache = mHwcBufferCaches[hwcId]; sp<GraphicBuffer> hwcBuffer; - hwcBufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, + hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); if (hwcBuffer != nullptr) { hwcHandle = hwcBuffer->handle; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 0efdf54418..6b228b00ac 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -47,6 +47,7 @@ #include "Transform.h" #include "DisplayHardware/HWComposer.h" +#include "DisplayHardware/HWComposerBufferCache.h" #include "RenderEngine/Mesh.h" #include "RenderEngine/Texture.h" @@ -383,20 +384,13 @@ public: #ifdef USE_HWC2 // ----------------------------------------------------------------------- - void eraseHwcLayer(int32_t hwcId) { - mHwcLayers.erase(hwcId); - - Mutex::Autolock lock(mHwcBufferCacheMutex); - mHwcBufferCaches.erase(hwcId); - } - bool hasHwcLayer(int32_t hwcId) { if (mHwcLayers.count(hwcId) == 0) { return false; } if (mHwcLayers[hwcId].layer->isAbandoned()) { ALOGI("Erasing abandoned layer %s on %d", mName.string(), hwcId); - eraseHwcLayer(hwcId); + mHwcLayers.erase(hwcId); return false; } return true; @@ -412,11 +406,8 @@ public: void setHwcLayer(int32_t hwcId, std::shared_ptr<HWC2::Layer>&& layer) { if (layer) { mHwcLayers[hwcId].layer = layer; - - Mutex::Autolock lock(mHwcBufferCacheMutex); - mHwcBufferCaches[hwcId] = HWComposerBufferCache(); } else { - eraseHwcLayer(hwcId); + mHwcLayers.erase(hwcId); } } @@ -511,7 +502,6 @@ private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener virtual void onFrameAvailable(const BufferItem& item) override; virtual void onFrameReplaced(const BufferItem& item) override; - virtual void onBuffersReleased() override; virtual void onSidebandStreamChanged() override; void commitTransaction(const State& stateToCommit); @@ -703,6 +693,7 @@ private: bool clearClientTarget; Rect displayFrame; FloatRect sourceCrop; + HWComposerBufferCache bufferCache; }; // A layer can be attached to multiple displays when operating in mirror mode @@ -710,12 +701,6 @@ private: // case we need to keep track. In non-mirror mode, a layer will have only one // HWCInfo. This map key is a display layerStack. std::unordered_map<int32_t, HWCInfo> mHwcLayers; - - // We need one HWComposerBufferCache for each HWC display. We cannot have - // HWComposerBufferCache in HWCInfo because HWCInfo can only be accessed - // from the main thread. - Mutex mHwcBufferCacheMutex; - std::unordered_map<int32_t, HWComposerBufferCache> mHwcBufferCaches; #else bool mIsGlesComposition; #endif diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp index 2fcbdba224..aa48c7dcee 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp +++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp @@ -237,19 +237,6 @@ void SurfaceFlingerConsumer::setContentsChangedListener( mContentsChangedListener = listener; } -void SurfaceFlingerConsumer::onBuffersReleased() { - sp<ContentsChangedListener> listener; - { // scope for the lock - Mutex::Autolock lock(mMutex); - ALOG_ASSERT(mFrameAvailableListener.unsafe_get() == mContentsChangedListener.unsafe_get()); - listener = mContentsChangedListener.promote(); - } - - if (listener != NULL) { - listener->onBuffersReleased(); - } -} - void SurfaceFlingerConsumer::onSidebandStreamChanged() { sp<ContentsChangedListener> listener; { // scope for the lock diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index cfa70ed4e8..1126233d60 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -35,7 +35,6 @@ public: static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8; struct ContentsChangedListener: public FrameAvailableListener { - virtual void onBuffersReleased() = 0; virtual void onSidebandStreamChanged() = 0; }; @@ -93,7 +92,6 @@ public: FrameEventHistoryDelta* outDelta) override; private: - virtual void onBuffersReleased(); virtual void onSidebandStreamChanged(); wp<ContentsChangedListener> mContentsChangedListener; |