summaryrefslogtreecommitdiffstats
path: root/gfx/layers/client/TiledContentClient.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/client/TiledContentClient.h')
-rw-r--r--gfx/layers/client/TiledContentClient.h406
1 files changed, 406 insertions, 0 deletions
diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h
new file mode 100644
index 0000000000..5657572a15
--- /dev/null
+++ b/gfx/layers/client/TiledContentClient.h
@@ -0,0 +1,406 @@
+/* -*- 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_TILEDCONTENTCLIENT_H
+#define MOZILLA_GFX_TILEDCONTENTCLIENT_H
+
+#include <cstdint> // for uint64_t, uint16_t, uint8_t
+#include <iosfwd> // for stringstream
+#include <utility> // for move
+#include "ClientLayerManager.h" // for ClientLayerManager
+#include "Units.h" // for CSSToParentLayerScale2D, ParentLayerPoint, LayerIntRect, LayerRect, LayerToParent...
+#include "gfxTypes.h" // for gfxContentType, gfxContentType::COLOR
+#include "mozilla/Maybe.h" // for Maybe
+#include "mozilla/RefPtr.h" // for RefPtr, operator==, operator!=
+#include "mozilla/TypedEnumBits.h" // for CastableTypedEnumResult, UnsignedIntegerTypeForEnum, MOZ_MAKE_ENUM_CLASS_BITWISE_...
+#include "mozilla/gfx/2D.h" // for DrawTarget, DrawTargetCapture
+#include "mozilla/gfx/Rect.h" // for IntRect
+#include "mozilla/layers/CompositableClient.h" // for CompositableClient
+#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, CompositableType, CompositableType::CONTENT_TILED
+#include "mozilla/layers/LayerManager.h" // for LayerManager, LayerManager::DrawPaintedLayerCallback
+#include "mozilla/layers/LayersMessages.h" // for TileDescriptor
+#include "mozilla/layers/LayersTypes.h" // for SurfaceMode, TextureDumpMode, Compress, SurfaceMode::SURFACE_OPAQUE
+#include "mozilla/layers/ShadowLayers.h" // for ShadowLayerForwarder
+#include "mozilla/layers/TextureClient.h" // for TextureClient
+#include "mozilla/layers/TextureClientPool.h" // for TextureClientAllocator
+#include "nsExpirationTracker.h" // for nsExpirationState
+#include "nsRegion.h" // for nsIntRegion
+#include "nsTArray.h" // for AutoTArray, nsTArray (ptr only)
+
+namespace mozilla {
+namespace layers {
+
+class ClientTiledPaintedLayer;
+class LayerMetricsWrapper;
+struct AsyncTransform;
+struct FrameMetrics;
+
+enum class TilePaintFlags : uint8_t {
+ None = 0x0,
+ Async = 0x1,
+ Progressive = 0x2,
+};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TilePaintFlags)
+
+void ShutdownTileCache();
+
+struct AcquiredBackBuffer {
+ AcquiredBackBuffer(gfx::DrawTarget* aTarget, gfx::DrawTargetCapture* aCapture,
+ gfx::DrawTarget* aBackBuffer,
+ const gfx::IntRect& aUpdatedRect,
+ AutoTArray<RefPtr<TextureClient>, 4>&& aTextureClients)
+ : mTarget(aTarget),
+ mCapture(aCapture),
+ mBackBuffer(aBackBuffer),
+ mUpdatedRect(aUpdatedRect),
+ mTextureClients(std::move(aTextureClients)) {}
+
+ AcquiredBackBuffer(const AcquiredBackBuffer&) = delete;
+ AcquiredBackBuffer& operator=(const AcquiredBackBuffer&) = delete;
+
+ AcquiredBackBuffer(AcquiredBackBuffer&&) = default;
+ AcquiredBackBuffer& operator=(AcquiredBackBuffer&&) = default;
+
+ RefPtr<gfx::DrawTarget> mTarget;
+ RefPtr<gfx::DrawTargetCapture> mCapture;
+ RefPtr<gfx::DrawTarget> mBackBuffer;
+ gfx::IntRect mUpdatedRect;
+ AutoTArray<RefPtr<TextureClient>, 4> mTextureClients;
+};
+
+/**
+ * Represent a single tile in tiled buffer. The buffer keeps tiles,
+ * each tile keeps a reference to a texture client and a read-lock. This
+ * read-lock is used to help implement a copy-on-write mechanism. The tile
+ * should be locked before being sent to the compositor. The compositor should
+ * unlock the read-lock as soon as it has finished with the buffer in the
+ * TextureHost to prevent more textures being created than is necessary.
+ * Ideal place to store per tile debug information.
+ */
+struct TileClient {
+ // Placeholder
+ TileClient();
+ ~TileClient();
+
+ TileClient(const TileClient& o);
+
+ TileClient& operator=(const TileClient& o);
+
+ bool operator==(const TileClient& o) const {
+ return mFrontBuffer == o.mFrontBuffer;
+ }
+
+ bool operator!=(const TileClient& o) const {
+ return mFrontBuffer != o.mFrontBuffer;
+ }
+
+ void SetTextureAllocator(TextureClientAllocator* aAllocator) {
+ mAllocator = aAllocator;
+ }
+
+ bool IsPlaceholderTile() const {
+ return mBackBuffer == nullptr && mFrontBuffer == nullptr;
+ }
+
+ void DiscardBuffers() {
+ DiscardFrontBuffer();
+ DiscardBackBuffer();
+ }
+
+ nsExpirationState* GetExpirationState() { return &mExpirationState; }
+
+ TileDescriptor GetTileDescriptor();
+
+ /**
+ * For debugging.
+ */
+ void Dump(std::stringstream& aStream);
+
+ /**
+ * Swaps the front and back buffers.
+ */
+ void Flip();
+
+ void DumpTexture(std::stringstream& aStream, TextureDumpMode aCompress) {
+ // TODO We should combine the OnWhite/OnBlack here an just output a single
+ // image.
+ CompositableClient::DumpTextureClient(aStream, mFrontBuffer, aCompress);
+ }
+
+ void GetSyncTextureSerials(SurfaceMode aMode, nsTArray<uint64_t>& aSerials);
+
+ /**
+ * Returns an unlocked TextureClient that can be used for writing new
+ * data to the tile. This may flip the front-buffer to the back-buffer if
+ * the front-buffer is still locked by the host, or does not have an
+ * internal buffer (and so will always be locked).
+ *
+ * If getting the back buffer required copying pixels from the front buffer
+ * then the copied region is stored in aAddPaintedRegion so the host side
+ * knows to upload it.
+ *
+ * If nullptr is returned, aTextureClientOnWhite is undefined.
+ */
+ Maybe<AcquiredBackBuffer> AcquireBackBuffer(CompositableClient&,
+ const nsIntRegion& aDirtyRegion,
+ const nsIntRegion& aVisibleRegion,
+ gfxContentType aContent,
+ SurfaceMode aMode,
+ TilePaintFlags aFlags);
+
+ void DiscardFrontBuffer();
+
+ void DiscardBackBuffer();
+
+ /* We wrap the back buffer in a class that disallows assignment
+ * so that we can track when ever it changes so that we can update
+ * the expiry tracker for expiring the back buffers */
+ class PrivateProtector {
+ public:
+ void Set(TileClient* container, RefPtr<TextureClient>);
+ void Set(TileClient* container, TextureClient*);
+ // Implicitly convert to TextureClient* because we can't chain
+ // implicit conversion that would happen on RefPtr<TextureClient>
+ operator TextureClient*() const { return mBuffer; }
+ RefPtr<TextureClient> operator->() { return mBuffer; }
+
+ private:
+ PrivateProtector& operator=(const PrivateProtector&);
+ RefPtr<TextureClient> mBuffer;
+ } mBackBuffer;
+ RefPtr<TextureClient> mBackBufferOnWhite;
+ RefPtr<TextureClient> mFrontBuffer;
+ RefPtr<TextureClient> mFrontBufferOnWhite;
+ RefPtr<TextureClientAllocator> mAllocator;
+ gfx::IntRect mUpdateRect;
+ bool mWasPlaceholder;
+#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
+ TimeStamp mLastUpdate;
+#endif
+ nsIntRegion mInvalidFront;
+ nsIntRegion mInvalidBack;
+ nsExpirationState mExpirationState;
+
+ private:
+ /*
+ * Copies dirty pixels from the front buffer into the back buffer,
+ * and records the copied region in aAddPaintedRegion.
+ */
+ void ValidateFromFront(const nsIntRegion& aDirtyRegion,
+ const nsIntRegion& aVisibleRegion,
+ gfx::DrawTarget* aBackBuffer, TilePaintFlags aFlags,
+ gfx::IntRect* aCopiedRegion,
+ AutoTArray<RefPtr<TextureClient>, 4>* aClients);
+};
+
+/**
+ * This struct stores all the data necessary to perform a paint so that it
+ * doesn't need to be recalculated on every repeated transaction.
+ */
+struct BasicTiledLayerPaintData {
+ /*
+ * The scroll offset of the content from the nearest ancestor layer that
+ * represents scrollable content with a display port set.
+ */
+ ParentLayerPoint mScrollOffset;
+
+ /*
+ * The scroll offset of the content from the nearest ancestor layer that
+ * represents scrollable content with a display port set, for the last
+ * layer update transaction.
+ */
+ ParentLayerPoint mLastScrollOffset;
+
+ /*
+ * The transform matrix to go from this layer's Layer units to
+ * the scroll ancestor's ParentLayer units. The "scroll ancestor" is
+ * the closest ancestor layer which scrolls, and is used to obtain
+ * the composition bounds that are relevant for this layer.
+ */
+ LayerToParentLayerMatrix4x4 mTransformToCompBounds;
+
+ /*
+ * The critical displayport of the content from the nearest ancestor layer
+ * that represents scrollable content with a display port set. isNothing()
+ * if a critical displayport is not set.
+ */
+ Maybe<LayerIntRect> mCriticalDisplayPort;
+
+ /*
+ * The render resolution of the document that the content this layer
+ * represents is in.
+ */
+ CSSToParentLayerScale2D mResolution;
+
+ /*
+ * The composition bounds of the layer, in Layer coordinates. This is
+ * used to make sure that tiled updates to regions that are visible to the
+ * user are grouped coherently.
+ */
+ LayerRect mCompositionBounds;
+
+ /*
+ * Low precision updates are always executed a tile at a time in repeated
+ * transactions. This counter is set to 1 on the first transaction of a low
+ * precision update, and incremented for each subsequent transaction.
+ */
+ uint16_t mLowPrecisionPaintCount;
+
+ /*
+ * Whether this is the first time this layer is painting
+ */
+ bool mFirstPaint : 1;
+
+ /*
+ * Whether there is further work to complete this paint. This is used to
+ * determine whether or not to repeat the transaction when painting
+ * progressively.
+ */
+ bool mPaintFinished : 1;
+
+ /*
+ * Whether or not there is an async transform animation active
+ */
+ bool mHasTransformAnimation : 1;
+
+ /*
+ * Initializes/clears data to prepare for paint action.
+ */
+ void ResetPaintData();
+};
+
+class SharedFrameMetricsHelper {
+ public:
+ SharedFrameMetricsHelper();
+ ~SharedFrameMetricsHelper();
+
+ /**
+ * This is called by the BasicTileLayer to determine if it is still interested
+ * in the update of this display-port to continue. We can return true here
+ * to abort the current update and continue with any subsequent ones. This
+ * is useful for slow-to-render pages when the display-port starts lagging
+ * behind enough that continuing to draw it is wasted effort.
+ */
+ bool UpdateFromCompositorFrameMetrics(const LayerMetricsWrapper& aLayer,
+ bool aHasPendingNewThebesContent,
+ bool aLowPrecision,
+ AsyncTransform& aViewTransform);
+
+ /**
+ * Determines if the compositor's upcoming composition bounds has fallen
+ * outside of the contents display port. If it has then the compositor
+ * will start to checker board. Checker boarding is when the compositor
+ * tries to composite a tile and it is not available. Historically
+ * a tile with a checker board pattern was used. Now a blank tile is used.
+ */
+ bool AboutToCheckerboard(const FrameMetrics& aContentMetrics,
+ const FrameMetrics& aCompositorMetrics);
+
+ private:
+ bool mLastProgressiveUpdateWasLowPrecision;
+ bool mProgressiveUpdateWasInDanger;
+};
+
+/**
+ * Provide an instance of TiledLayerBuffer backed by drawable TextureClients.
+ * This buffer provides an implementation of ValidateTile using a
+ * thebes callback and can support painting using a single paint buffer.
+ * Whether a single paint buffer is used is controlled by
+ * StaticPrefs::PerTileDrawing().
+ */
+class ClientTiledLayerBuffer {
+ public:
+ ClientTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
+ CompositableClient& aCompositableClient)
+ : mPaintedLayer(aPaintedLayer),
+ mCompositableClient(aCompositableClient),
+ mLastPaintContentType(gfxContentType::COLOR),
+ mLastPaintSurfaceMode(SurfaceMode::SURFACE_OPAQUE),
+ mWasLastPaintProgressive(false) {}
+
+ virtual void PaintThebes(const nsIntRegion& aNewValidRegion,
+ const nsIntRegion& aPaintRegion,
+ const nsIntRegion& aDirtyRegion,
+ LayerManager::DrawPaintedLayerCallback aCallback,
+ void* aCallbackData, TilePaintFlags aFlags) = 0;
+ virtual void GetSyncTextureSerials(const nsIntRegion& aPaintRegion,
+ const nsIntRegion& aDirtyRegion,
+ nsTArray<uint64_t>& aSerials) {
+ return;
+ }
+
+ virtual bool SupportsProgressiveUpdate() = 0;
+ virtual bool ProgressiveUpdate(
+ const nsIntRegion& aValidRegion, const nsIntRegion& aInvalidRegion,
+ const nsIntRegion& aOldValidRegion, nsIntRegion& aOutDrawnRegion,
+ BasicTiledLayerPaintData* aPaintData,
+ LayerManager::DrawPaintedLayerCallback aCallback,
+ void* aCallbackData) = 0;
+ virtual void ResetPaintedAndValidState() = 0;
+
+ virtual const nsIntRegion& GetValidRegion() = 0;
+
+ virtual bool IsLowPrecision() const = 0;
+
+ virtual void Dump(std::stringstream& aStream, const char* aPrefix,
+ bool aDumpHtml, TextureDumpMode aCompress) {}
+
+ const CSSToParentLayerScale2D& GetFrameResolution() {
+ return mFrameResolution;
+ }
+ void SetFrameResolution(const CSSToParentLayerScale2D& aResolution) {
+ mFrameResolution = aResolution;
+ }
+
+ bool HasFormatChanged() const;
+
+ protected:
+ void UnlockTile(TileClient& aTile);
+ gfxContentType GetContentType(SurfaceMode* aMode = nullptr) const;
+
+ ClientTiledPaintedLayer& mPaintedLayer;
+ CompositableClient& mCompositableClient;
+
+ gfxContentType mLastPaintContentType;
+ SurfaceMode mLastPaintSurfaceMode;
+ CSSToParentLayerScale2D mFrameResolution;
+
+ bool mWasLastPaintProgressive;
+};
+
+class TiledContentClient : public CompositableClient {
+ public:
+ TiledContentClient(ClientLayerManager* aManager, const char* aName = "")
+ : CompositableClient(aManager->AsShadowForwarder()), mName(aName) {}
+
+ protected:
+ ~TiledContentClient() {}
+
+ public:
+ virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
+
+ void Dump(std::stringstream& aStream, const char* aPrefix = "",
+ bool aDumpHtml = false,
+ TextureDumpMode aCompress = TextureDumpMode::Compress) override;
+
+ TextureInfo GetTextureInfo() const override {
+ return TextureInfo(CompositableType::CONTENT_TILED);
+ }
+
+ virtual ClientTiledLayerBuffer* GetTiledBuffer() = 0;
+ virtual ClientTiledLayerBuffer* GetLowPrecisionTiledBuffer() = 0;
+
+ enum TiledBufferType { TILED_BUFFER, LOW_PRECISION_TILED_BUFFER };
+ virtual void UpdatedBuffer(TiledBufferType aType) = 0;
+
+ private:
+ const char* mName;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // MOZILLA_GFX_TILEDCONTENTCLIENT_H