diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-07-20 21:32:29 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-07-20 21:32:29 +0000 |
commit | bde9db506f38bb8caa6df016ca25fef5410b88b4 (patch) | |
tree | 3b9705a2b734870b03a52e7884dd42921481b459 | |
parent | 0a3e7847012108f047a6582ebfb88026d640277f (diff) | |
parent | 9fdb7e0c8204aba5666d8e9f7f526682c8efc203 (diff) | |
download | native-pie-dr1-dev.tar.gz |
Merge "SF: Add GL texture pool" into pi-devpie-dr1-dev
-rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 10 | ||||
-rw-r--r-- | services/surfaceflinger/Client.cpp | 44 | ||||
-rw-r--r-- | services/surfaceflinger/ContainerLayer.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 37 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 11 |
7 files changed, 78 insertions, 52 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index fda7906744..12267adbc0 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -63,7 +63,7 @@ BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, cons mRefreshPending(false) { ALOGV("Creating Layer %s", name.string()); - mFlinger->getRenderEngine().genTextures(1, &mTextureName); + mTextureName = mFlinger->getNewTexture(); mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false; @@ -706,8 +706,12 @@ void BufferLayer::onFirstRef() { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, true); mProducer = new MonitoredProducer(producer, mFlinger, this); - mConsumer = new BufferLayerConsumer(consumer, - mFlinger->getRenderEngine(), mTextureName, this); + { + // Grab the SF state lock during this since it's the only safe way to access RenderEngine + Mutex::Autolock lock(mFlinger->mStateLock); + mConsumer = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, + this); + } mConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mConsumer->setContentsChangedListener(this); mConsumer->setName(mName); diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 077469b5e1..0b59147c5a 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -170,48 +170,8 @@ status_t Client::createSurface( } } - /* - * createSurface must be called from the GL thread so that it can - * have access to the GL context. - */ - class MessageCreateLayer : public MessageBase { - SurfaceFlinger* flinger; - Client* client; - sp<IBinder>* handle; - sp<IGraphicBufferProducer>* gbp; - status_t result; - const String8& name; - uint32_t w, h; - PixelFormat format; - uint32_t flags; - sp<Layer>* parent; - 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, int32_t windowType, int32_t ownerUid, - sp<IGraphicBufferProducer>* gbp, - sp<Layer>* parent) - : flinger(flinger), client(client), - handle(handle), gbp(gbp), result(NO_ERROR), - name(name), w(w), h(h), format(format), flags(flags), - parent(parent), windowType(windowType), ownerUid(ownerUid) { - } - status_t getResult() const { return result; } - virtual bool handler() { - result = flinger->createLayer(name, client, w, h, format, flags, - windowType, ownerUid, handle, gbp, parent); - return true; - } - }; - - sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), - name, this, w, h, format, flags, handle, - windowType, ownerUid, gbp, &parent); - mFlinger->postMessageSync(msg); - return static_cast<MessageCreateLayer*>( msg.get() )->getResult(); + return mFlinger->createLayer(name, this, w, h, format, flags, windowType, + ownerUid, handle, gbp, &parent); } status_t Client::destroySurface(const sp<IBinder>& handle) { diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index 543f60a624..b352b96762 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -35,6 +35,8 @@ public: bool isVisible() const override; void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; + + bool isCreatedFromMainThread() const override { return true; } }; } // namespace android diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 9150c3f895..a14bb98d8d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -130,17 +130,26 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& n // drawing state & current state are identical mDrawingState = mCurrentState; - const auto& hwc = flinger->getHwComposer(); - const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY); - nsecs_t displayPeriod = activeConfig->getVsyncPeriod(); - mFrameTracker.setDisplayRefreshPeriod(displayPeriod); - CompositorTiming compositorTiming; flinger->getCompositorTiming(&compositorTiming); mFrameEventHistory.initializeCompositorTiming(compositorTiming); } -void Layer::onFirstRef() {} +void Layer::onFirstRef() NO_THREAD_SAFETY_ANALYSIS { + if (!isCreatedFromMainThread()) { + // Grab the SF state lock during this since it's the only way to safely access HWC + mFlinger->mStateLock.lock(); + } + + const auto& hwc = mFlinger->getHwComposer(); + const auto& activeConfig = hwc.getActiveConfig(HWC_DISPLAY_PRIMARY); + nsecs_t displayPeriod = activeConfig->getVsyncPeriod(); + mFrameTracker.setDisplayRefreshPeriod(displayPeriod); + + if (!isCreatedFromMainThread()) { + mFlinger->mStateLock.unlock(); + } +} Layer::~Layer() { sp<Client> c(mClientRef.promote()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index f4ae21aad5..22396796ed 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -360,6 +360,11 @@ public: */ virtual bool isFixedSize() const { return true; } + // Most layers aren't created from the main thread, and therefore need to + // grab the SF state lock to access HWC, but ContainerLayer does, so we need + // to avoid grabbing the lock again to avoid deadlock + virtual bool isCreatedFromMainThread() const { return false; } + bool isPendingRemoval() const { return mPendingRemoval; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 68594661b0..cf53930fa1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -503,6 +503,27 @@ void SurfaceFlinger::bootFinished() postMessageAsync(readProperties); } +uint32_t SurfaceFlinger::getNewTexture() { + { + std::lock_guard lock(mTexturePoolMutex); + if (!mTexturePool.empty()) { + uint32_t name = mTexturePool.back(); + mTexturePool.pop_back(); + ATRACE_INT("TexturePoolSize", mTexturePool.size()); + return name; + } + + // The pool was too small, so increase it for the future + ++mTexturePoolSize; + } + + // The pool was empty, so we need to get a new texture name directly using a + // blocking call to the main thread + uint32_t name = 0; + postMessageSync(new LambdaMessage([&]() { getRenderEngine().genTextures(1, &name); })); + return name; +} + void SurfaceFlinger::deleteTextureAsync(uint32_t texture) { class MessageDestroyGLTexture : public MessageBase { RE::RenderEngine& engine; @@ -1841,6 +1862,17 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) getBE().mTotalTime += elapsedTime; } getBE().mLastSwapTime = currentTime; + + { + std::lock_guard lock(mTexturePoolMutex); + const size_t refillCount = mTexturePoolSize - mTexturePool.size(); + if (refillCount > 0) { + const size_t offset = mTexturePool.size(); + mTexturePool.resize(mTexturePoolSize); + getRenderEngine().genTextures(refillCount, mTexturePool.data() + offset); + ATRACE_INT("TexturePoolSize", mTexturePool.size()); + } + } } void SurfaceFlinger::rebuildLayerStacks() { @@ -3632,10 +3664,13 @@ String8 SurfaceFlinger::getUniqueLayerName(const String8& name) // Tack on our counter whether there is a hit or not, so everyone gets a tag String8 uniqueName = name + "#" + String8(std::to_string(dupeCounter).c_str()); + // Grab the state lock since we're accessing mCurrentState + Mutex::Autolock lock(mStateLock); + // Loop over layers until we're sure there is no matching name while (matchFound) { matchFound = false; - mDrawingState.traverseInZOrder([&](Layer* layer) { + mCurrentState.traverseInZOrder([&](Layer* layer) { if (layer->getName() == uniqueName) { matchFound = true; uniqueName = name + "#" + String8(std::to_string(++dupeCounter).c_str()); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index afcefdb948..8f724e98d1 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -320,6 +320,10 @@ public: return getDefaultDisplayDeviceLocked(); } + // Obtains a name from the texture pool, or, if the pool is empty, posts a + // synchronous message to the main thread to obtain one on the fly + uint32_t getNewTexture(); + // utility function to delete a texture on the main thread void deleteTextureAsync(uint32_t texture); @@ -864,6 +868,13 @@ private: std::atomic<bool> mRefreshPending{false}; + // We maintain a pool of pre-generated texture names to hand out to avoid + // layer creation needing to run on the main thread (which it would + // otherwise need to do to access RenderEngine). + std::mutex mTexturePoolMutex; + uint32_t mTexturePoolSize = 0; + std::vector<uint32_t> mTexturePool; + /* ------------------------------------------------------------------------ * Feature prototyping */ |