/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MOZILLA_GFX_RemoteTextureMap_H #define MOZILLA_GFX_RemoteTextureMap_H #include #include #include #include #include #include #include #include #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/gfx/Types.h" // for SurfaceFormat #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor #include "mozilla/layers/TextureHost.h" #include "mozilla/Monitor.h" #include "mozilla/StaticPtr.h" #include "mozilla/ThreadSafeWeakPtr.h" #include "mozilla/UniquePtr.h" #include "mozilla/webrender/WebRenderTypes.h" class nsISerialEventTarget; namespace mozilla { namespace gl { class SharedSurface; } namespace layers { class CompositableHost; class RemoteTextureHostWrapper; class TextureData; class TextureHost; /** * A class provides API for remote texture owners. */ class RemoteTextureOwnerClient final { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureOwnerClient) explicit RemoteTextureOwnerClient(const base::ProcessId aForPid); bool IsRegistered(const RemoteTextureOwnerId aOwnerId); void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId, bool aIsSyncMode); void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId); void UnregisterAllTextureOwners(); void PushTexture(const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, UniquePtr&& aTextureData, const std::shared_ptr& aSharedSurface); void PushDummyTexture(const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId); void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId, const ipc::Shmem& aDestShmem, const gfx::IntSize& aSize); UniquePtr CreateOrRecycleBufferTextureData( const RemoteTextureOwnerId aOwnerId, gfx::IntSize aSize, gfx::SurfaceFormat aFormat); std::shared_ptr GetRecycledSharedSurface( const RemoteTextureOwnerId aOwnerId); const base::ProcessId mForPid; protected: ~RemoteTextureOwnerClient(); std::unordered_set mOwnerIds; }; /** * A class to map RemoteTextureId to remote texture(TextureHost). * Remote textures are provided by texture owner. */ class RemoteTextureMap { public: static void Init(); static void Shutdown(); static RemoteTextureMap* Get() { return sInstance; } RemoteTextureMap(); ~RemoteTextureMap(); // Push remote texture data and gl::SharedSurface from texture owner. // The texture data is used for creating TextureHost. // gl::SharedSurface is pushed only when the surface needs to be kept alive // during TextureHost usage. The texture data and the surface might be // recycled when TextureHost is destroyed. void PushTexture(const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, UniquePtr&& aTextureData, RefPtr& aTextureHost, const std::shared_ptr& aSharedSurface); void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, const ipc::Shmem& aDestShmem, const gfx::IntSize& aSize); // aIsSyncMode defines if RemoteTextureMap::GetRemoteTextureForDisplayList() // works synchronously. void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, bool aIsSyncMode); void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerIds, const base::ProcessId aForPid); void UnregisterTextureOwners( const std::unordered_set& aOwnerIds, const base::ProcessId aForPid); // Get TextureHost that is used for building wr display list. // In sync mode, mRemoteTextureForDisplayList holds TextureHost of mTextureId. // In async mode, it could be previous remote texture's TextureHost that is // compatible to the mTextureId's TextureHost. void GetRemoteTextureForDisplayList( RemoteTextureHostWrapper* aTextureHostWrapper); // Get ExternalImageId of remote texture for WebRender rendering. // This synchronously waits until remote texture becomes ready. wr::MaybeExternalImageId GetExternalImageIdOfRemoteTextureSync( const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid); void ReleaseRemoteTextureHostForDisplayList( RemoteTextureHostWrapper* aTextureHostWrapper); RefPtr GetOrCreateRemoteTextureHostWrapper( const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, const gfx::IntSize aSize, const TextureFlags aFlags); void UnregisterRemoteTextureHostWrapper(const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid); void RegisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, CompositableHost* aListener); void UnregisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, CompositableHost* aListener); UniquePtr GetRecycledBufferTextureData( const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, gfx::IntSize aSize, gfx::SurfaceFormat aFormat); std::shared_ptr GetRecycledSharedSurface( const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid); static RefPtr CreateRemoteTexture(TextureData* aTextureData, TextureFlags aTextureFlags); protected: // Holds data related to remote texture struct TextureDataHolder { TextureDataHolder(const RemoteTextureId aTextureId, RefPtr aTextureHost, UniquePtr&& aTextureData, const std::shared_ptr& aSharedSurface); const RemoteTextureId mTextureId; // TextureHost of remote texture // Compositable ref of the mTextureHost should be updated within mMonitor. // The compositable ref is used to check if TextureHost(remote texture) is // still in use by WebRender. RefPtr mTextureHost; // Holds BufferTextureData of TextureHost UniquePtr mTextureData; // Holds gl::SharedSurface of TextureHost std::shared_ptr mSharedSurface; }; struct TextureOwner { bool mIsSyncMode = true; // Holds TextureDataHolders that wait to be used for building wr display // list. std::deque> mWaitingTextureDataHolders; // Holds TextureDataHolders that are used for building wr display list. std::deque> mUsingTextureDataHolders; RemoteTextureId mLatestTextureId = {0}; CompositableTextureHostRef mLatestTextureHost; std::stack> mRecycledTextures; std::queue> mRecycledSharedSurfaces; }; // Holds data related to remote texture wrapper struct RemoteTextureHostWrapperHolder { explicit RemoteTextureHostWrapperHolder( RefPtr aRemoteTextureHostWrapper); const RefPtr mRemoteTextureHostWrapper; // Hold compositable ref of remote texture of the RemoteTextureId in async // mode. It is for keeping the texture alive during its rendering by // WebRender. CompositableTextureHostRef mAsyncRemoteTextureHost; }; void UpdateTexture(const MonitorAutoLock& aProofOfLock, RemoteTextureMap::TextureOwner* aOwner, const RemoteTextureId aTextureId); void KeepTextureDataAliveForTextureHostIfNecessary( const MonitorAutoLock& aProofOfLock, std::deque>& aHolders); RemoteTextureMap::TextureOwner* GetTextureOwner( const MonitorAutoLock& aProofOfLock, const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid); Monitor mMonitor MOZ_UNANNOTATED; std::map, UniquePtr> mTextureOwners; std::map, UniquePtr> mRemoteTextureHostWrapperHolders; std::map, RefPtr> mRemoteTexturePushListeners; static StaticAutoPtr sInstance; }; } // namespace layers } // namespace mozilla #endif // MOZILLA_GFX_RemoteTextureMap_H