michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef MOZILLA_GFX_BUFFERCLIENT_H michael@0: #define MOZILLA_GFX_BUFFERCLIENT_H michael@0: michael@0: #include // for uint64_t michael@0: #include // for vector michael@0: #include // for map michael@0: #include "mozilla/Assertions.h" // for MOZ_CRASH michael@0: #include "mozilla/RefPtr.h" // for TemporaryRef, RefCounted michael@0: #include "mozilla/gfx/Types.h" // for SurfaceFormat michael@0: #include "mozilla/layers/CompositorTypes.h" michael@0: #include "mozilla/layers/LayersTypes.h" // for LayersBackend michael@0: #include "mozilla/layers/PCompositableChild.h" // for PCompositableChild michael@0: #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class CompositableClient; michael@0: class TextureClient; michael@0: class BufferTextureClient; michael@0: class ImageBridgeChild; michael@0: class CompositableForwarder; michael@0: class CompositableChild; michael@0: class SurfaceDescriptor; michael@0: class TextureClientData; michael@0: michael@0: /** michael@0: * CompositableClient manages the texture-specific logic for composite layers, michael@0: * independently of the layer. It is the content side of a CompositableClient/ michael@0: * CompositableHost pair. michael@0: * michael@0: * CompositableClient's purpose is to send texture data to the compositor side michael@0: * along with any extra information about how the texture is to be composited. michael@0: * Things like opacity or transformation belong to layer and not compositable. michael@0: * michael@0: * Since Compositables are independent of layers it is possible to create one, michael@0: * connect it to the compositor side, and start sending images to it. This alone michael@0: * is arguably not very useful, but it means that as long as a shadow layer can michael@0: * do the proper magic to find a reference to the right CompositableHost on the michael@0: * Compositor side, a Compositable client can be used outside of the main michael@0: * shadow layer forwarder machinery that is used on the main thread. michael@0: * michael@0: * The first step is to create a Compositable client and call Connect(). michael@0: * Connect() creates the underlying IPDL actor (see CompositableChild) and the michael@0: * corresponding CompositableHost on the other side. michael@0: * michael@0: * To do in-transaction texture transfer (the default), call michael@0: * ShadowLayerForwarder::Attach(CompositableClient*, ShadowableLayer*). This michael@0: * will let the LayerComposite on the compositor side know which CompositableHost michael@0: * to use for compositing. michael@0: * michael@0: * To do async texture transfer (like async-video), the CompositableClient michael@0: * should be created with a different CompositableForwarder (like michael@0: * ImageBridgeChild) and attachment is done with michael@0: * CompositableForwarder::AttachAsyncCompositable that takes an identifier michael@0: * instead of a CompositableChild, since the CompositableClient is not managed michael@0: * by this layer forwarder (the matching uses a global map on the compositor side, michael@0: * see CompositableMap in ImageBridgeParent.cpp) michael@0: * michael@0: * Subclasses: Thebes layers use ContentClients, ImageLayers use ImageClients, michael@0: * Canvas layers use CanvasClients (but ImageHosts). We have a different subclass michael@0: * where we have a different way of interfacing with the textures - in terms of michael@0: * drawing into the compositable and/or passing its contents to the compostior. michael@0: */ michael@0: class CompositableClient michael@0: { michael@0: protected: michael@0: virtual ~CompositableClient(); michael@0: michael@0: public: michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableClient) michael@0: michael@0: CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = 0); michael@0: michael@0: virtual TextureInfo GetTextureInfo() const = 0; michael@0: michael@0: LayersBackend GetCompositorBackendType() const; michael@0: michael@0: TemporaryRef michael@0: CreateBufferTextureClient(gfx::SurfaceFormat aFormat, michael@0: TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT, michael@0: gfx::BackendType aMoz2dBackend = gfx::BackendType::NONE); michael@0: michael@0: TemporaryRef michael@0: CreateTextureClientForDrawing(gfx::SurfaceFormat aFormat, michael@0: TextureFlags aTextureFlags, michael@0: gfx::BackendType aMoz2dBackend, michael@0: const gfx::IntSize& aSizeHint); michael@0: michael@0: virtual void SetDescriptorFromReply(TextureIdentifier aTextureId, michael@0: const SurfaceDescriptor& aDescriptor) michael@0: { michael@0: MOZ_CRASH("If you want to call this, you should have implemented it"); michael@0: } michael@0: michael@0: /** michael@0: * Establishes the connection with compositor side through IPDL michael@0: */ michael@0: virtual bool Connect(); michael@0: michael@0: void Destroy(); michael@0: michael@0: PCompositableChild* GetIPDLActor() const; michael@0: michael@0: // should only be called by a CompositableForwarder michael@0: virtual void SetIPDLActor(CompositableChild* aChild); michael@0: michael@0: CompositableForwarder* GetForwarder() const michael@0: { michael@0: return mForwarder; michael@0: } michael@0: michael@0: /** michael@0: * This identifier is what lets us attach async compositables with a shadow michael@0: * layer. It is not used if the compositable is used with the regular shadow michael@0: * layer forwarder. michael@0: * michael@0: * If this returns zero, it means the compositable is not async (it is used michael@0: * on the main thread). michael@0: */ michael@0: uint64_t GetAsyncID() const; michael@0: michael@0: /** michael@0: * Tells the Compositor to create a TextureHost for this TextureClient. michael@0: */ michael@0: virtual bool AddTextureClient(TextureClient* aClient); michael@0: michael@0: /** michael@0: * A hook for the Compositable to execute whatever it held off for next transaction. michael@0: */ michael@0: virtual void OnTransaction(); michael@0: michael@0: /** michael@0: * A hook for the when the Compositable is detached from it's layer. michael@0: */ michael@0: virtual void OnDetach() {} michael@0: michael@0: /** michael@0: * Clear any resources that are not immediately necessary. This may be called michael@0: * in low-memory conditions. michael@0: */ michael@0: virtual void ClearCachedResources() {} michael@0: michael@0: static CompositableClient* FromIPDLActor(PCompositableChild* aActor); michael@0: michael@0: /** michael@0: * Allocate and deallocate a CompositableChild actor. michael@0: * michael@0: * CompositableChild is an implementation detail of CompositableClient that is not michael@0: * exposed to the rest of the code base. CreateIPDLActor and DestroyIPDLActor michael@0: * are for use with the managing IPDL protocols only (so that they can michael@0: * implement AllocCompositableChild and DeallocPCompositableChild). michael@0: */ michael@0: static PCompositableChild* CreateIPDLActor(); michael@0: michael@0: static bool DestroyIPDLActor(PCompositableChild* actor); michael@0: michael@0: void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0); michael@0: michael@0: protected: michael@0: CompositableChild* mCompositableChild; michael@0: CompositableForwarder* mForwarder; michael@0: // Some layers may want to enforce some flags to all their textures michael@0: // (like disallowing tiling) michael@0: TextureFlags mTextureFlags; michael@0: michael@0: friend class CompositableChild; michael@0: }; michael@0: michael@0: } // namespace michael@0: } // namespace michael@0: michael@0: #endif