1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef MOZILLA_GFX_MULTITILEDCONTENTCLIENT_H
8 #define MOZILLA_GFX_MULTITILEDCONTENTCLIENT_H
9 
10 #include "ClientLayerManager.h"                 // for ClientLayerManager
11 #include "nsRegion.h"                           // for nsIntRegion
12 #include "mozilla/gfx/2D.h"                     // for gfx::Tile
13 #include "mozilla/gfx/Point.h"                  // for IntPoint
14 #include "mozilla/layers/CompositableClient.h"  // for CompositableClient
15 #include "mozilla/layers/LayersMessages.h"      // for TileDescriptor
16 #include "mozilla/layers/TiledContentClient.h"  // for ClientTiledPaintedLayer
17 #include "mozilla/UniquePtr.h"                  // for UniquePtr
18 #include "TiledLayerBuffer.h"                   // for TiledLayerBuffer
19 
20 namespace mozilla {
21 namespace layers {
22 
23 class ClientLayerManager;
24 
25 class ClientMultiTiledLayerBuffer
26     : public TiledLayerBuffer<ClientMultiTiledLayerBuffer, TileClient>,
27       public ClientTiledLayerBuffer {
28   friend class TiledLayerBuffer<ClientMultiTiledLayerBuffer, TileClient>;
29 
30  public:
31   ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer& aPaintedLayer,
32                               CompositableClient& aCompositableClient,
33                               ClientLayerManager* aManager,
34                               SharedFrameMetricsHelper* aHelper);
35 
36   void PaintThebes(const nsIntRegion& aNewValidRegion,
37                    const nsIntRegion& aPaintRegion,
38                    const nsIntRegion& aDirtyRegion,
39                    LayerManager::DrawPaintedLayerCallback aCallback,
40                    void* aCallbackData,
41                    TilePaintFlags aFlags = TilePaintFlags::None) override;
42 
SupportsProgressiveUpdate()43   bool SupportsProgressiveUpdate() override { return true; }
44   /**
45    * Performs a progressive update of a given tiled buffer.
46    * See ComputeProgressiveUpdateRegion below for parameter documentation.
47    * aOutDrawnRegion is an outparameter that contains the region that was
48    * drawn, and which can now be added to the layer's valid region.
49    */
50   bool ProgressiveUpdate(const nsIntRegion& aValidRegion,
51                          const nsIntRegion& aInvalidRegion,
52                          const nsIntRegion& aOldValidRegion,
53                          nsIntRegion& aOutDrawnRegion,
54                          BasicTiledLayerPaintData* aPaintData,
55                          LayerManager::DrawPaintedLayerCallback aCallback,
56                          void* aCallbackData) override;
57 
ResetPaintedAndValidState()58   void ResetPaintedAndValidState() override {
59     mValidRegion.SetEmpty();
60     mTiles.mSize.width = 0;
61     mTiles.mSize.height = 0;
62     DiscardBuffers();
63     mRetainedTiles.Clear();
64   }
65 
GetValidRegion()66   const nsIntRegion& GetValidRegion() override {
67     return TiledLayerBuffer::GetValidRegion();
68   }
69 
IsLowPrecision()70   bool IsLowPrecision() const override {
71     return TiledLayerBuffer::IsLowPrecision();
72   }
73 
Dump(std::stringstream & aStream,const char * aPrefix,bool aDumpHtml,TextureDumpMode aCompress)74   void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml,
75             TextureDumpMode aCompress) override {
76     TiledLayerBuffer::Dump(aStream, aPrefix, aDumpHtml, aCompress);
77   }
78 
79   void ReadLock();
80 
81   void Release();
82 
83   void DiscardBuffers();
84 
85   SurfaceDescriptorTiles GetSurfaceDescriptorTiles();
86 
SetResolution(float aResolution)87   void SetResolution(float aResolution) {
88     if (mResolution == aResolution) {
89       return;
90     }
91 
92     Update(nsIntRegion(), nsIntRegion(), nsIntRegion(), TilePaintFlags::None);
93     mResolution = aResolution;
94   }
95 
96  protected:
97   bool ValidateTile(TileClient& aTile, const nsIntPoint& aTileRect,
98                     nsIntRegion& aDirtyRegion, TilePaintFlags aFlags);
99 
100   void Update(const nsIntRegion& aNewValidRegion,
101               const nsIntRegion& aPaintRegion, const nsIntRegion& aDirtyRegion,
102               TilePaintFlags aFlags);
103 
GetPlaceholderTile()104   TileClient GetPlaceholderTile() const { return TileClient(); }
105 
106  private:
107   RefPtr<ClientLayerManager> mManager;
108   LayerManager::DrawPaintedLayerCallback mCallback;
109   void* mCallbackData;
110 
111   // The region that will be made valid during Update(). Once Update() is
112   // completed then this is identical to mValidRegion.
113   nsIntRegion mNewValidRegion;
114 
115   SharedFrameMetricsHelper* mSharedFrameMetricsHelper;
116 
117   // Parameters that are collected during Update for a paint before they
118   // are either executed or replayed on the paint thread.
119   AutoTArray<gfx::Tile, 4> mPaintTiles;
120   AutoTArray<UniquePtr<PaintTask>, 4> mPaintTasks;
121 
122   /**
123    * While we're adding tiles, this is used to keep track of the position of
124    * the top-left of the top-left-most tile.  When we come to wrap the tiles in
125    * TiledDrawTarget we subtract the value of this member from each tile's
126    * offset so that all the tiles have a positive offset, then add a
127    * translation to the TiledDrawTarget to compensate.  This is important so
128    * that the mRect of the TiledDrawTarget is always at a positive x/y
129    * position, otherwise its GetSize() methods will be broken.
130    */
131   gfx::IntPoint mTilingOrigin;
132   /**
133    * Calculates the region to update in a single progressive update transaction.
134    * This employs some heuristics to update the most 'sensible' region to
135    * update at this point in time, and how large an update should be performed
136    * at once to maintain visual coherency.
137    *
138    * aInvalidRegion is the current invalid region.
139    * aOldValidRegion is the valid region of mTiledBuffer at the beginning of the
140    * current transaction.
141    * aRegionToPaint will be filled with the region to update. This may be empty,
142    * which indicates that there is no more work to do.
143    * aIsRepeated should be true if this function has already been called during
144    * this transaction.
145    *
146    * Returns true if it should be called again, false otherwise. In the case
147    * that aRegionToPaint is empty, this will return aIsRepeated for convenience.
148    */
149   bool ComputeProgressiveUpdateRegion(const nsIntRegion& aInvalidRegion,
150                                       const nsIntRegion& aOldValidRegion,
151                                       nsIntRegion& aRegionToPaint,
152                                       BasicTiledLayerPaintData* aPaintData,
153                                       bool aIsRepeated);
154 
155   void MaybeSyncTextures(const nsIntRegion& aPaintRegion,
156                          const TilesPlacement& aNewTiles,
157                          const gfx::IntSize& aScaledTileSize);
158 };
159 
160 /**
161  * An implementation of TiledContentClient that supports
162  * multiple tiles and a low precision buffer.
163  */
164 class MultiTiledContentClient : public TiledContentClient {
165  public:
166   MultiTiledContentClient(ClientTiledPaintedLayer& aPaintedLayer,
167                           ClientLayerManager* aManager);
168 
169  protected:
~MultiTiledContentClient()170   ~MultiTiledContentClient() {
171     MOZ_COUNT_DTOR(MultiTiledContentClient);
172 
173     mTiledBuffer.DiscardBuffers();
174     mLowPrecisionTiledBuffer.DiscardBuffers();
175   }
176 
177  public:
178   void ClearCachedResources() override;
179   void UpdatedBuffer(TiledBufferType aType) override;
180 
GetTiledBuffer()181   ClientTiledLayerBuffer* GetTiledBuffer() override { return &mTiledBuffer; }
GetLowPrecisionTiledBuffer()182   ClientTiledLayerBuffer* GetLowPrecisionTiledBuffer() override {
183     if (mHasLowPrecision) {
184       return &mLowPrecisionTiledBuffer;
185     }
186     return nullptr;
187   }
188 
189  private:
190   SharedFrameMetricsHelper mSharedFrameMetricsHelper;
191   ClientMultiTiledLayerBuffer mTiledBuffer;
192   ClientMultiTiledLayerBuffer mLowPrecisionTiledBuffer;
193   bool mHasLowPrecision;
194 };
195 
196 }  // namespace layers
197 }  // namespace mozilla
198 
199 #endif  // MOZILLA_GFX_MULTITILEDCONTENTCLIENT_H
200