зеркало из https://github.com/mozilla/gecko-dev.git
279 строки
9.8 KiB
C++
279 строки
9.8 KiB
C++
/* -*- 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_BUFFERHOST_H
|
|
#define MOZILLA_GFX_BUFFERHOST_H
|
|
|
|
#include <stdint.h> // for uint64_t
|
|
#include <stdio.h> // for FILE
|
|
#include "gfxRect.h" // for gfxRect
|
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
|
#include "mozilla/Attributes.h" // for override
|
|
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted, etc
|
|
#include "mozilla/gfx/MatrixFwd.h" // for Matrix4x4
|
|
#include "mozilla/gfx/Point.h" // for Point
|
|
#include "mozilla/gfx/Polygon.h" // for Polygon
|
|
#include "mozilla/gfx/Rect.h" // for Rect
|
|
#include "mozilla/gfx/Types.h" // for SamplingFilter
|
|
#include "mozilla/ipc/ProtocolUtils.h"
|
|
#include "mozilla/layers/Compositor.h" // for Compositor
|
|
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
|
|
#include "mozilla/layers/Effects.h" // for Texture Effect
|
|
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
|
|
#include "mozilla/layers/LayersMessages.h"
|
|
#include "mozilla/layers/TextureHost.h" // for TextureHost
|
|
#include "mozilla/mozalloc.h" // for operator delete
|
|
#include "nsCOMPtr.h" // for already_AddRefed
|
|
#include "nsRegion.h" // for nsIntRegion
|
|
#include "nscore.h" // for nsACString
|
|
#include "Units.h" // for CSSToScreenScale
|
|
|
|
namespace mozilla {
|
|
namespace gfx {
|
|
class DataSourceSurface;
|
|
} // namespace gfx
|
|
|
|
namespace layers {
|
|
|
|
class Layer;
|
|
class LayerComposite;
|
|
class ImageHost;
|
|
class Compositor;
|
|
class ThebesBufferData;
|
|
class TiledContentHost;
|
|
class CompositableParentManager;
|
|
class WebRenderImageHost;
|
|
class ContentHost;
|
|
class ContentHostTexture;
|
|
class HostLayerManager;
|
|
struct EffectChain;
|
|
|
|
struct ImageCompositeNotificationInfo {
|
|
base::ProcessId mImageBridgeProcessId;
|
|
ImageCompositeNotification mNotification;
|
|
};
|
|
|
|
struct AsyncCompositableRef {
|
|
AsyncCompositableRef() : mProcessId(mozilla::ipc::kInvalidProcessId) {}
|
|
AsyncCompositableRef(base::ProcessId aProcessId,
|
|
const CompositableHandle& aHandle)
|
|
: mProcessId(aProcessId), mHandle(aHandle) {}
|
|
explicit operator bool() const { return !!mHandle; }
|
|
base::ProcessId mProcessId;
|
|
CompositableHandle mHandle;
|
|
};
|
|
|
|
/**
|
|
* The compositor-side counterpart to CompositableClient. Responsible for
|
|
* updating textures and data about textures from IPC and how textures are
|
|
* composited (tiling, double buffering, etc.).
|
|
*
|
|
* Update (for images/canvases) and UpdateThebes (for Thebes) are called during
|
|
* the layers transaction to update the Compositbale's textures from the
|
|
* content side. The actual update (and any syncronous upload) is done by the
|
|
* TextureHost, but it is coordinated by the CompositableHost.
|
|
*
|
|
* Composite is called by the owning layer when it is composited.
|
|
* CompositableHost will use its TextureHost(s) and call Compositor::DrawQuad to
|
|
* do the actual rendering.
|
|
*/
|
|
class CompositableHost {
|
|
protected:
|
|
virtual ~CompositableHost();
|
|
|
|
public:
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableHost)
|
|
explicit CompositableHost(const TextureInfo& aTextureInfo);
|
|
|
|
static already_AddRefed<CompositableHost> Create(
|
|
const TextureInfo& aTextureInfo, bool aUseWebRender);
|
|
|
|
virtual CompositableType GetType() = 0;
|
|
|
|
// If base class overrides, it should still call the parent implementation
|
|
virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider);
|
|
|
|
// composite the contents of this buffer host to the compositor's surface
|
|
virtual void Composite(Compositor* aCompositor, LayerComposite* aLayer,
|
|
EffectChain& aEffectChain, float aOpacity,
|
|
const gfx::Matrix4x4& aTransform,
|
|
const gfx::SamplingFilter aSamplingFilter,
|
|
const gfx::IntRect& aClipRect,
|
|
const nsIntRegion* aVisibleRegion = nullptr,
|
|
const Maybe<gfx::Polygon>& aGeometry = Nothing()) = 0;
|
|
|
|
/**
|
|
* Update the content host.
|
|
* aUpdated is the region which should be updated.
|
|
*/
|
|
virtual bool UpdateThebes(const ThebesBufferData& aData,
|
|
const nsIntRegion& aUpdated,
|
|
const nsIntRegion& aOldValidRegionBack) {
|
|
NS_ERROR("should be implemented or not used");
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns the front buffer.
|
|
* *aPictureRect (if non-null, and the returned TextureHost is non-null)
|
|
* is set to the picture rect.
|
|
*/
|
|
virtual TextureHost* GetAsTextureHost(gfx::IntRect* aPictureRect = nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
virtual gfx::IntSize GetImageSize() {
|
|
MOZ_ASSERT(false, "Should have been overridden");
|
|
return gfx::IntSize();
|
|
}
|
|
|
|
const TextureInfo& GetTextureInfo() const { return mTextureInfo; }
|
|
|
|
/**
|
|
* Adds a mask effect using this texture as the mask, if possible.
|
|
* @return true if the effect was added, false otherwise.
|
|
*/
|
|
bool AddMaskEffect(EffectChain& aEffects, const gfx::Matrix4x4& aTransform);
|
|
|
|
void RemoveMaskEffect();
|
|
|
|
TextureSourceProvider* GetTextureSourceProvider() const;
|
|
|
|
Layer* GetLayer() const { return mLayer; }
|
|
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
|
|
|
|
virtual ContentHost* AsContentHost() { return nullptr; }
|
|
virtual ContentHostTexture* AsContentHostTexture() { return nullptr; }
|
|
virtual ImageHost* AsImageHost() { return nullptr; }
|
|
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
|
|
virtual WebRenderImageHost* AsWebRenderImageHost() { return nullptr; }
|
|
|
|
typedef uint32_t AttachFlags;
|
|
static const AttachFlags NO_FLAGS = 0;
|
|
static const AttachFlags ALLOW_REATTACH = 1;
|
|
static const AttachFlags KEEP_ATTACHED = 2;
|
|
static const AttachFlags FORCE_DETACH = 2;
|
|
|
|
virtual void Attach(Layer* aLayer, TextureSourceProvider* aProvider,
|
|
AttachFlags aFlags = NO_FLAGS) {
|
|
MOZ_ASSERT(aProvider);
|
|
NS_ASSERTION(aFlags & ALLOW_REATTACH || !mAttached,
|
|
"Re-attaching compositables must be explicitly authorised");
|
|
SetTextureSourceProvider(aProvider);
|
|
SetLayer(aLayer);
|
|
mAttached = true;
|
|
mKeepAttached = aFlags & KEEP_ATTACHED;
|
|
}
|
|
// Detach this compositable host from its layer.
|
|
// If we are used for async video, then it is not safe to blindly detach since
|
|
// we might be re-attached to a different layer. aLayer is the layer which the
|
|
// caller expects us to be attached to, we will only detach if we are in fact
|
|
// attached to that layer. If we are part of a normal layer, then we will be
|
|
// detached in any case. if aLayer is null, then we will only detach if we are
|
|
// not async.
|
|
// Only force detach if the IPDL tree is being shutdown.
|
|
virtual void Detach(Layer* aLayer = nullptr, AttachFlags aFlags = NO_FLAGS) {
|
|
if (!mKeepAttached || aLayer == mLayer || aFlags & FORCE_DETACH) {
|
|
SetLayer(nullptr);
|
|
mAttached = false;
|
|
mKeepAttached = false;
|
|
}
|
|
}
|
|
bool IsAttached() { return mAttached; }
|
|
|
|
virtual void Dump(std::stringstream& aStream, const char* aPrefix = "",
|
|
bool aDumpHtml = false) {}
|
|
static void DumpTextureHost(std::stringstream& aStream,
|
|
TextureHost* aTexture);
|
|
|
|
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() {
|
|
return nullptr;
|
|
}
|
|
|
|
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) = 0;
|
|
|
|
struct TimedTexture {
|
|
CompositableTextureHostRef mTexture;
|
|
TimeStamp mTimeStamp;
|
|
gfx::IntRect mPictureRect;
|
|
int32_t mFrameID;
|
|
int32_t mProducerID;
|
|
};
|
|
virtual void UseTextureHost(const nsTArray<TimedTexture>& aTextures);
|
|
virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
|
|
TextureHost* aTextureOnWhite);
|
|
virtual void RemoveTextureHost(TextureHost* aTexture);
|
|
|
|
// Called every time this is composited
|
|
void BumpFlashCounter() {
|
|
mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX
|
|
? DIAGNOSTIC_FLASH_COUNTER_MAX
|
|
: mFlashCounter + 1;
|
|
}
|
|
|
|
uint64_t GetCompositorBridgeID() const { return mCompositorBridgeID; }
|
|
|
|
const AsyncCompositableRef& GetAsyncRef() const { return mAsyncRef; }
|
|
void SetAsyncRef(const AsyncCompositableRef& aRef) { mAsyncRef = aRef; }
|
|
|
|
void SetCompositorBridgeID(uint64_t aID) { mCompositorBridgeID = aID; }
|
|
|
|
virtual bool Lock() { return false; }
|
|
|
|
virtual void Unlock() {}
|
|
|
|
virtual already_AddRefed<TexturedEffect> GenEffect(
|
|
const gfx::SamplingFilter aSamplingFilter) {
|
|
return nullptr;
|
|
}
|
|
|
|
/// Called when shutting down the layer tree.
|
|
/// This is a good place to clear all potential gpu resources before the
|
|
/// widget is is destroyed.
|
|
virtual void CleanupResources() {}
|
|
|
|
virtual void BindTextureSource() {}
|
|
|
|
virtual uint32_t GetDroppedFrames() { return 0; }
|
|
|
|
protected:
|
|
HostLayerManager* GetLayerManager() const;
|
|
|
|
protected:
|
|
TextureInfo mTextureInfo;
|
|
AsyncCompositableRef mAsyncRef;
|
|
uint64_t mCompositorBridgeID;
|
|
RefPtr<TextureSourceProvider> mTextureSourceProvider;
|
|
Layer* mLayer;
|
|
uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
|
|
bool mAttached;
|
|
bool mKeepAttached;
|
|
};
|
|
|
|
class AutoLockCompositableHost final {
|
|
public:
|
|
explicit AutoLockCompositableHost(CompositableHost* aHost) : mHost(aHost) {
|
|
mSucceeded = (mHost && mHost->Lock());
|
|
}
|
|
|
|
~AutoLockCompositableHost() {
|
|
if (mSucceeded && mHost) {
|
|
mHost->Unlock();
|
|
}
|
|
}
|
|
|
|
bool Failed() const { return !mSucceeded; }
|
|
|
|
private:
|
|
RefPtr<CompositableHost> mHost;
|
|
bool mSucceeded;
|
|
};
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|
|
|
|
#endif
|