diff options
| author | 2019-08-16 14:35:07 -0700 | |
|---|---|---|
| committer | 2019-09-26 10:04:12 -0700 | |
| commit | b4c6e5850f16d045abcb4e3308b7556749a61be0 (patch) | |
| tree | 04389ac878b1b6609976c2388861bd8c2f849784 | |
| parent | 04c70c4c49f02e660edda8f24638efdda54f38b6 (diff) | |
[Mirror Layers] Added clone function to layers (1/4)
Added a cloning function to each layer in preparation for mirroring
Test: Nothing to test yet since no calls
Bug: 131622422
Change-Id: Iba0692b75c4d99841de48f40ed55b3dbccf2b9b9
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 19 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 20 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 27 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/ContainerLayer.cpp | 7 | ||||
| -rw-r--r-- | services/surfaceflinger/ContainerLayer.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 9 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 15 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 21 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 13 |
14 files changed, 121 insertions, 28 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index fba235d397..d189846dd5 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -58,7 +58,7 @@ namespace android { BufferLayer::BufferLayer(const LayerCreationArgs& args) : Layer(args), - mTextureName(args.flinger->getNewTexture()), + mTextureName(args.textureName), mCompositionLayer{mFlinger->getCompositionEngine().createLayer( compositionengine::LayerCreationArgs{this})} { ALOGV("Creating Layer %s", args.name.string()); @@ -70,7 +70,13 @@ BufferLayer::BufferLayer(const LayerCreationArgs& args) } BufferLayer::~BufferLayer() { - mFlinger->deleteTextureAsync(mTextureName); + if (!isClone()) { + // The original layer and the clone layer share the same texture. Therefore, only one of + // the layers, in this case the original layer, needs to handle the deletion. The original + // layer and the clone should be removed at the same time so there shouldn't be any issue + // with the clone layer trying to use the deleted texture. + mFlinger->deleteTextureAsync(mTextureName); + } const int32_t layerID = getSequence(); mFlinger->mTimeStats->onDestroy(layerID); mFlinger->mFrameTracer->onDestroy(layerID); @@ -722,6 +728,15 @@ void BufferLayer::getDrawingTransformMatrix(bool filteringEnabled, float outMatr mBufferInfo.mTransform, filteringEnabled); } +void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { + Layer::setInitialValuesForClone(clonedFrom); + + sp<BufferLayer> bufferClonedFrom = static_cast<BufferLayer*>(clonedFrom.get()); + mPremultipliedAlpha = bufferClonedFrom->mPremultipliedAlpha; + mPotentialCursor = bufferClonedFrom->mPotentialCursor; + mProtectedByApp = bufferClonedFrom->mProtectedByApp; +} + } // namespace android #if defined(__gl_h_) diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index f0a30e319a..b2c06183a6 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -194,6 +194,7 @@ protected: bool mRefreshPending{false}; ui::Dataspace translateDataspace(ui::Dataspace dataspace); + void setInitialValuesForClone(const sp<Layer>& clonedFrom); private: // Returns true if this layer requires filtering diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index fcabedf63e..eb13f658d9 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -461,12 +461,7 @@ void BufferQueueLayer::onFirstRef() { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, true); mProducer = new MonitoredProducer(producer, mFlinger, 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 = new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this); mConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mConsumer->setContentsChangedListener(this); mConsumer->setName(mName); @@ -476,7 +471,7 @@ void BufferQueueLayer::onFirstRef() { mProducer->setMaxDequeuedBufferCount(2); } - if (const auto display = mFlinger->getDefaultDisplayDevice()) { + if (const auto display = mFlinger->getDefaultDisplayDeviceLocked()) { updateTransformHint(display); } } @@ -531,4 +526,15 @@ void BufferQueueLayer::gatherBufferInfo() { mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse(); } +sp<Layer> BufferQueueLayer::createClone() { + const String8 name = mName + " (Mirror)"; + LayerCreationArgs args = + LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, 0, LayerMetadata()); + args.textureName = mTextureName; + sp<BufferQueueLayer> layer = new BufferQueueLayer(args); + layer->setInitialValuesForClone(this); + + return layer; +} + } // namespace android diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index 9374741ddb..36dff156e1 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -31,6 +31,7 @@ namespace android { */ class BufferQueueLayer : public BufferLayer, public BufferLayerConsumer::ContentsChangedListener { public: + // Only call while mStateLock is held explicit BufferQueueLayer(const LayerCreationArgs&); ~BufferQueueLayer() override; @@ -81,6 +82,7 @@ private: status_t updateFrameNumber(nsecs_t latchTime) override; void latchPerFrameState(compositionengine::LayerFECompositionState&) const override; + sp<Layer> createClone() override; // ----------------------------------------------------------------------- // Interface implementation for BufferLayerConsumer::ContentsChangedListener diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index ad05bc8671..30fdbe14e8 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -48,10 +48,17 @@ BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) { mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; mCurrentState.dataspace = ui::Dataspace::V0_SRGB; + if (const auto display = args.displayDevice) { + updateTransformHint(display); + } } BufferStateLayer::~BufferStateLayer() { - if (mBufferInfo.mBuffer != nullptr) { + // The original layer and the clone layer share the same texture and buffer. Therefore, only + // one of the layers, in this case the original layer, needs to handle the deletion. The + // original layer and the clone should be removed at the same time so there shouldn't be any + // issue with the clone layer trying to use the texture. + if (mBufferInfo.mBuffer != nullptr && !isClone()) { // Ensure that mBuffer is uncached from RenderEngine here, as // RenderEngine may have been using the buffer as an external texture // after the client uncached the buffer. @@ -545,14 +552,6 @@ void BufferStateLayer::latchPerFrameState( mFrameNumber++; } -void BufferStateLayer::onFirstRef() { - BufferLayer::onFirstRef(); - - if (const auto display = mFlinger->getDefaultDisplayDevice()) { - updateTransformHint(display); - } -} - void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) { std::lock_guard lock(mMutex); if (!clientCacheId.isValid()) { @@ -668,4 +667,14 @@ Rect BufferStateLayer::computeCrop(const State& s) { return s.crop; } +sp<Layer> BufferStateLayer::createClone() { + const String8 name = mName + " (Mirror)"; + LayerCreationArgs args = + LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, 0, LayerMetadata()); + args.textureName = mTextureName; + sp<BufferStateLayer> layer = new BufferStateLayer(args); + layer->mHwcSlotGenerator = mHwcSlotGenerator; + layer->setInitialValuesForClone(this); + return layer; +} } // namespace android diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 52063fcc58..e951ccf97a 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -124,13 +124,13 @@ private: status_t updateFrameNumber(nsecs_t latchTime) override; void latchPerFrameState(compositionengine::LayerFECompositionState&) const override; + sp<Layer> createClone() override; // Crop that applies to the buffer Rect computeCrop(const State& s); private: friend class SlotGenerationTest; - void onFirstRef() override; bool willPresentCurrentTransaction() const; static const std::array<float, 16> IDENTITY_MATRIX; diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 99805d9da2..5b620543ac 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -107,6 +107,14 @@ ui::Dataspace ColorLayer::getDataSpace() const { return mDrawingState.dataspace; } +sp<Layer> ColorLayer::createClone() { + String8 name = mName + " (Mirror)"; + sp<ColorLayer> layer = new ColorLayer( + LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, 0, LayerMetadata())); + layer->setInitialValuesForClone(this); + return layer; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 16921df356..634a80003a 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -50,6 +50,8 @@ protected: compositionengine::LayerFE::ClientCompositionTargetSettings&) override; std::shared_ptr<compositionengine::Layer> mCompositionLayer; + + sp<Layer> createClone() override; }; } // namespace android diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp index 4a1130365a..cb50d9ff6d 100644 --- a/services/surfaceflinger/ContainerLayer.cpp +++ b/services/surfaceflinger/ContainerLayer.cpp @@ -30,4 +30,11 @@ bool ContainerLayer::isVisible() const { return false; } +sp<Layer> ContainerLayer::createClone() { + String8 name = mName + " (Mirror)"; + sp<ContainerLayer> layer = new ContainerLayer( + LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, 0, LayerMetadata())); + layer->setInitialValuesForClone(this); + return layer; +} } // namespace android diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index c3624f6d7d..b48d471bde 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -32,6 +32,9 @@ public: bool isVisible() const override; bool isCreatedFromMainThread() const override { return true; } + +protected: + sp<Layer> createClone() override; }; } // namespace android diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index ba948cfdbc..52a09b35d1 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2015,6 +2015,15 @@ Region Layer::debugGetVisibleRegionOnDefaultDisplay() const { return outputLayer->getState().visibleRegion; } +void Layer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { + // copy drawing state from cloned layer + mDrawingState = clonedFrom->mDrawingState; + mClonedFrom = clonedFrom; + + // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple + // InputWindows per client token yet. + mDrawingState.inputInfo.token = nullptr; +} // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 8771ccd08e..96970ace89 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -91,6 +91,8 @@ struct LayerCreationArgs { LayerMetadata metadata; pid_t callingPid; uid_t callingUid; + sp<const DisplayDevice> displayDevice; + uint32_t textureName; }; class Layer : public compositionengine::LayerFE { @@ -465,6 +467,13 @@ public: virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } virtual bool needsFiltering(const sp<const DisplayDevice>&) const { return false; } +protected: + virtual sp<Layer> createClone() = 0; + sp<Layer> getClonedFrom() { return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr; } + + bool isClone() { return getClonedFrom() != nullptr; } + virtual void setInitialValuesForClone(const sp<Layer>& clonedFrom); + public: /* * compositionengine::LayerFE overrides @@ -912,6 +921,12 @@ private: // to help debugging. pid_t mCallingPid; uid_t mCallingUid; + + // The current layer is a clone of mClonedFrom. This means that this layer will update it's + // properties based on mClonedFrom. When mClonedFrom latches a new buffer for BufferLayers, + // this layer will update it's buffer. When mClonedFrom updates it's drawing state, children, + // and relatives, this layer will update as well. + wp<Layer> mClonedFrom; }; } // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 41afb5da55..e3cf84aa1a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3532,8 +3532,18 @@ status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const break; } - sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer( - LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata))); + sp<BufferQueueLayer> layer; + LayerCreationArgs args = + LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)); + args.textureName = getNewTexture(); + { + // Grab the SF state lock during this since it's the only safe way to access + // RenderEngine when creating a BufferLayerConsumer + // TODO: Check if this lock is still needed here + Mutex::Autolock lock(mStateLock); + layer = getFactory().createBufferQueueLayer(args); + } + status_t err = layer->setDefaultBufferProperties(w, h, format); if (err == NO_ERROR) { *handle = layer->getHandle(); @@ -3549,8 +3559,11 @@ status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, const uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata, sp<IBinder>* handle, sp<Layer>* outLayer) { - sp<BufferStateLayer> layer = getFactory().createBufferStateLayer( - LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata))); + LayerCreationArgs args = + LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)); + args.displayDevice = getDefaultDisplayDevice(); + args.textureName = getNewTexture(); + sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args); *handle = layer->getHandle(); *outLayer = layer; diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 20dfed65e2..f29e2ddd33 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -883,11 +883,14 @@ struct BufferLayerVariant : public BaseLayerVariant<LayerProperties> { FlingerLayerType layer = Base::template createLayerWithFactory<BufferQueueLayer>(test, [test]() { - return new BufferQueueLayer( - LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(), - String8("test-layer"), LayerProperties::WIDTH, - LayerProperties::HEIGHT, - LayerProperties::LAYER_FLAGS, LayerMetadata())); + sp<Client> client; + String8 name("test-layer"); + LayerCreationArgs args = + LayerCreationArgs(test->mFlinger.mFlinger.get(), client, name, + LayerProperties::WIDTH, LayerProperties::HEIGHT, + LayerProperties::LAYER_FLAGS, LayerMetadata()); + args.textureName = test->mFlinger.mutableTexturePool().back(); + return new BufferQueueLayer(args); }); LayerProperties::setupLayerState(test, layer); |