/* * Copyright 2018 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. */ #pragma once #ifndef LOG_TAG #warning "ComposerResources.h included without LOG_TAG" #endif #include #include #include #include #include #include namespace android { class GraphicBufferMapper; namespace hardware { namespace graphics { namespace composer { namespace V2_1 { namespace hal { // wrapper for IMapper to import buffers and sideband streams class ComposerHandleImporter { public: ComposerHandleImporter(); bool init(); Error importBuffer(const native_handle_t* rawHandle, const native_handle_t** outBufferHandle); void freeBuffer(const native_handle_t* bufferHandle); Error importStream(const native_handle_t* rawHandle, const native_handle_t** outStreamHandle); void freeStream(const native_handle_t* streamHandle); private: GraphicBufferMapper& mMapper; }; class ComposerHandleCache { public: enum class HandleType { INVALID, BUFFER, STREAM, }; ComposerHandleCache(ComposerHandleImporter& importer, HandleType type, uint32_t cacheSize); // must be initialized later with initCache ComposerHandleCache(ComposerHandleImporter& importer); ~ComposerHandleCache(); ComposerHandleCache(const ComposerHandleCache&) = delete; ComposerHandleCache& operator=(const ComposerHandleCache&) = delete; bool initCache(HandleType type, uint32_t cacheSize); size_t getCacheSize() const; Error lookupCache(uint32_t slot, const native_handle_t** outHandle); Error updateCache(uint32_t slot, const native_handle_t* handle, const native_handle** outReplacedHandle); // when fromCache is true, look up in the cache; otherwise, update the cache Error getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle, const native_handle_t** outHandle, const native_handle** outReplacedHandle); private: ComposerHandleImporter& mImporter; HandleType mHandleType = HandleType::INVALID; std::vector mHandles; }; // layer resource class ComposerLayerResource { public: ComposerLayerResource(ComposerHandleImporter& importer, uint32_t bufferCacheSize); virtual ~ComposerLayerResource() = default; Error getBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle, const native_handle_t** outHandle, const native_handle** outReplacedHandle); Error getSidebandStream(uint32_t slot, bool fromCache, const native_handle_t* inHandle, const native_handle_t** outHandle, const native_handle** outReplacedHandle); protected: ComposerHandleCache mBufferCache; ComposerHandleCache mSidebandStreamCache; }; // display resource class ComposerDisplayResource { public: enum class DisplayType { PHYSICAL, VIRTUAL, }; virtual ~ComposerDisplayResource() = default; ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer, uint32_t outputBufferCacheSize); bool initClientTargetCache(uint32_t cacheSize); size_t getClientTargetCacheSize() const; size_t getOutputBufferCacheSize() const; bool isVirtual() const; Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle, const native_handle_t** outHandle, const native_handle** outReplacedHandle); Error getOutputBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle, const native_handle_t** outHandle, const native_handle** outReplacedHandle); bool addLayer(Layer layer, std::unique_ptr layerResource); bool removeLayer(Layer layer); ComposerLayerResource* findLayerResource(Layer layer); std::vector getLayers() const; void setMustValidateState(bool mustValidate); bool mustValidate() const; protected: const DisplayType mType; ComposerHandleCache mClientTargetCache; ComposerHandleCache mOutputBufferCache; bool mMustValidate; std::unordered_map> mLayerResources; }; class ComposerResources { public: static std::unique_ptr create(); ComposerResources() = default; virtual ~ComposerResources() = default; bool init(); using RemoveDisplay = std::function& layers)>; void clear(RemoveDisplay removeDisplay); bool hasDisplay(Display display); Error addPhysicalDisplay(Display display); Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize); Error removeDisplay(Display display); Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize); Error getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize); Error getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize); Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize); Error removeLayer(Display display, Layer layer); void setDisplayMustValidateState(Display display, bool mustValidate); bool mustValidateDisplay(Display display); // When a buffer in the cache is replaced by a new one, we must keep it // alive until it has been replaced in ComposerHal because it is still using // the old buffer. class ReplacedHandle { public: explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {} ReplacedHandle(const ReplacedHandle&) = delete; ReplacedHandle& operator=(const ReplacedHandle&) = delete; ~ReplacedHandle() { reset(); } bool isBuffer() { return mIsBuffer; } void reset(ComposerHandleImporter* importer = nullptr, const native_handle_t* handle = nullptr) { if (mHandle) { if (mIsBuffer) { mImporter->freeBuffer(mHandle); } else { mImporter->freeStream(mHandle); } } mImporter = importer; mHandle = handle; } private: bool mIsBuffer; ComposerHandleImporter* mImporter = nullptr; const native_handle_t* mHandle = nullptr; }; Error getDisplayClientTarget(Display display, uint32_t slot, bool fromCache, const native_handle_t* rawHandle, const native_handle_t** outBufferHandle, ReplacedHandle* outReplacedBuffer); Error getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache, const native_handle_t* rawHandle, const native_handle_t** outBufferHandle, ReplacedHandle* outReplacedBuffer); Error getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache, const native_handle_t* rawHandle, const native_handle_t** outBufferHandle, ReplacedHandle* outReplacedBuffer); Error getLayerSidebandStream(Display display, Layer layer, const native_handle_t* rawHandle, const native_handle_t** outStreamHandle, ReplacedHandle* outReplacedStream); protected: virtual std::unique_ptr createDisplayResource( ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize); virtual std::unique_ptr createLayerResource(uint32_t bufferCacheSize); ComposerDisplayResource* findDisplayResourceLocked(Display display); ComposerHandleImporter mImporter; std::mutex mDisplayResourcesMutex; std::unordered_map> mDisplayResources; private: enum class Cache { CLIENT_TARGET, OUTPUT_BUFFER, LAYER_BUFFER, LAYER_SIDEBAND_STREAM, }; Error getHandle(Display display, Layer layer, uint32_t slot, Cache cache, bool fromCache, const native_handle_t* rawHandle, const native_handle_t** outHandle, ReplacedHandle* outReplacedHandle); }; } // namespace hal } // namespace V2_1 } // namespace composer } // namespace graphics } // namespace hardware } // namespace android