LCOV - code coverage report
Current view: directory - gfx/layers - ThebesLayerBuffer.h (source / functions) Found Hit Coverage
Test: app.info Lines: 28 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  * ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Corporation code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Robert O'Callahan <robert@ocallahan.org>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef THEBESLAYERBUFFER_H_
      39                 : #define THEBESLAYERBUFFER_H_
      40                 : 
      41                 : #include "gfxContext.h"
      42                 : #include "gfxASurface.h"
      43                 : #include "nsRegion.h"
      44                 : 
      45                 : namespace mozilla {
      46                 : namespace layers {
      47                 : 
      48                 : class ThebesLayer;
      49                 : 
      50                 : /**
      51                 :  * This class encapsulates the buffer used to retain ThebesLayer contents,
      52                 :  * i.e., the contents of the layer's GetVisibleRegion().
      53                 :  * 
      54                 :  * This is a cairo/Thebes surface, but with a literal twist. Scrolling
      55                 :  * causes the layer's visible region to move. We want to keep
      56                 :  * reusing the same surface if the region size hasn't changed, but we don't
      57                 :  * want to keep moving the contents of the surface around in memory. So
      58                 :  * we use a trick.
      59                 :  * Consider just the vertical case, and suppose the buffer is H pixels
      60                 :  * high and we're scrolling down by N pixels. Instead of copying the
      61                 :  * buffer contents up by N pixels, we leave the buffer contents in place,
      62                 :  * and paint content rows H to H+N-1 into rows 0 to N-1 of the buffer.
      63                 :  * Then we can refresh the screen by painting rows N to H-1 of the buffer
      64                 :  * at row 0 on the screen, and then painting rows 0 to N-1 of the buffer
      65                 :  * at row H-N on the screen.
      66                 :  * mBufferRotation.y would be N in this example.
      67                 :  */
      68                 : class ThebesLayerBuffer {
      69                 : public:
      70                 :   typedef gfxASurface::gfxContentType ContentType;
      71                 : 
      72                 :   /**
      73                 :    * Controls the size of the backing buffer of this.
      74                 :    * - SizedToVisibleBounds: the backing buffer is exactly the same
      75                 :    *   size as the bounds of ThebesLayer's visible region
      76                 :    * - ContainsVisibleBounds: the backing buffer is large enough to
      77                 :    *   fit visible bounds.  May be larger.
      78                 :    */
      79                 :   enum BufferSizePolicy {
      80                 :     SizedToVisibleBounds,
      81                 :     ContainsVisibleBounds
      82                 :   };
      83                 : 
      84               0 :   ThebesLayerBuffer(BufferSizePolicy aBufferSizePolicy)
      85                 :     : mBufferRotation(0,0)
      86               0 :     , mBufferSizePolicy(aBufferSizePolicy)
      87                 :   {
      88               0 :     MOZ_COUNT_CTOR(ThebesLayerBuffer);
      89               0 :   }
      90               0 :   virtual ~ThebesLayerBuffer()
      91               0 :   {
      92               0 :     MOZ_COUNT_DTOR(ThebesLayerBuffer);
      93               0 :   }
      94                 : 
      95                 :   /**
      96                 :    * Wipe out all retained contents. Call this when the entire
      97                 :    * buffer becomes invalid.
      98                 :    */
      99               0 :   void Clear()
     100                 :   {
     101               0 :     mBuffer = nsnull;
     102               0 :     mBufferRect.SetEmpty();
     103               0 :   }
     104                 : 
     105                 :   /**
     106                 :    * This is returned by BeginPaint. The caller should draw into mContext.
     107                 :    * mRegionToDraw must be drawn. mRegionToInvalidate has been invalidated
     108                 :    * by ThebesLayerBuffer and must be redrawn on the screen.
     109                 :    * mRegionToInvalidate is set when the buffer has changed from
     110                 :    * opaque to transparent or vice versa, since the details of rendering can
     111                 :    * depend on the buffer type.  mDidSelfCopy is true if we kept our buffer
     112                 :    * but used MovePixels() to shift its content.
     113                 :    */
     114               0 :   struct PaintState {
     115               0 :     PaintState()
     116               0 :       : mDidSelfCopy(false)
     117               0 :     {}
     118                 : 
     119                 :     nsRefPtr<gfxContext> mContext;
     120                 :     nsIntRegion mRegionToDraw;
     121                 :     nsIntRegion mRegionToInvalidate;
     122                 :     bool mDidSelfCopy;
     123                 :   };
     124                 : 
     125                 :   enum {
     126                 :     PAINT_WILL_RESAMPLE = 0x01
     127                 :   };
     128                 :   /**
     129                 :    * Start a drawing operation. This returns a PaintState describing what
     130                 :    * needs to be drawn to bring the buffer up to date in the visible region.
     131                 :    * This queries aLayer to get the currently valid and visible regions.
     132                 :    * The returned mContext may be null if mRegionToDraw is empty.
     133                 :    * Otherwise it must not be null.
     134                 :    * mRegionToInvalidate will contain mRegionToDraw.
     135                 :    * @param aFlags when PAINT_WILL_RESAMPLE is passed, this indicates that
     136                 :    * buffer will be resampled when rendering (i.e the effective transform
     137                 :    * combined with the scale for the resolution is not just an integer
     138                 :    * translation). This will disable buffer rotation (since we don't want
     139                 :    * to resample across the rotation boundary) and will ensure that we
     140                 :    * make the entire buffer contents valid (since we don't want to sample
     141                 :    * invalid pixels outside the visible region, if the visible region doesn't
     142                 :    * fill the buffer bounds).
     143                 :    */
     144                 :   PaintState BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
     145                 :                         PRUint32 aFlags);
     146                 : 
     147                 :   enum {
     148                 :     ALLOW_REPEAT = 0x01
     149                 :   };
     150                 :   /**
     151                 :    * Return a new surface of |aSize| and |aType|.
     152                 :    * @param aFlags if ALLOW_REPEAT is set, then the buffer should be configured
     153                 :    * to allow repeat-mode, otherwise it should be in pad (clamp) mode
     154                 :    */
     155                 :   virtual already_AddRefed<gfxASurface>
     156                 :   CreateBuffer(ContentType aType, const nsIntSize& aSize, PRUint32 aFlags) = 0;
     157                 : 
     158                 :   /**
     159                 :    * Get the underlying buffer, if any. This is useful because we can pass
     160                 :    * in the buffer as the default "reference surface" if there is one.
     161                 :    * Don't use it for anything else!
     162                 :    */
     163               0 :   gfxASurface* GetBuffer() { return mBuffer; }
     164                 : 
     165                 : protected:
     166                 :   enum XSide {
     167                 :     LEFT, RIGHT
     168                 :   };
     169                 :   enum YSide {
     170                 :     TOP, BOTTOM
     171                 :   };
     172                 :   nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide);
     173                 :   void DrawBufferQuadrant(gfxContext* aTarget, XSide aXSide, YSide aYSide,
     174                 :                           float aOpacity);
     175                 :   void DrawBufferWithRotation(gfxContext* aTarget, float aOpacity);
     176                 : 
     177                 :   /**
     178                 :    * |BufferRect()| is the rect of device pixels that this
     179                 :    * ThebesLayerBuffer covers.  That is what DrawBufferWithRotation()
     180                 :    * will paint when it's called.
     181                 :    */
     182               0 :   const nsIntRect& BufferRect() const { return mBufferRect; }
     183               0 :   const nsIntPoint& BufferRotation() const { return mBufferRotation; }
     184                 : 
     185                 :   already_AddRefed<gfxASurface>
     186               0 :   SetBuffer(gfxASurface* aBuffer,
     187                 :             const nsIntRect& aBufferRect, const nsIntPoint& aBufferRotation)
     188                 :   {
     189               0 :     nsRefPtr<gfxASurface> tmp = mBuffer.forget();
     190               0 :     mBuffer = aBuffer;
     191               0 :     mBufferRect = aBufferRect;
     192               0 :     mBufferRotation = aBufferRotation;
     193               0 :     return tmp.forget();
     194                 :   }
     195                 : 
     196                 :   /**
     197                 :    * Get a context at the specified resolution for updating |aBounds|,
     198                 :    * which must be contained within a single quadrant.
     199                 :    */
     200                 :   already_AddRefed<gfxContext>
     201                 :   GetContextForQuadrantUpdate(const nsIntRect& aBounds);
     202                 : 
     203                 : private:
     204               0 :   bool BufferSizeOkFor(const nsIntSize& aSize)
     205                 :   {
     206               0 :     return (aSize == mBufferRect.Size() ||
     207                 :             (SizedToVisibleBounds != mBufferSizePolicy &&
     208               0 :              aSize < mBufferRect.Size()));
     209                 :   }
     210                 : 
     211                 :   nsRefPtr<gfxASurface> mBuffer;
     212                 :   /** The area of the ThebesLayer that is covered by the buffer as a whole */
     213                 :   nsIntRect             mBufferRect;
     214                 :   /**
     215                 :    * The x and y rotation of the buffer. Conceptually the buffer
     216                 :    * has its origin translated to mBufferRect.TopLeft() - mBufferRotation,
     217                 :    * is tiled to fill the plane, and the result is clipped to mBufferRect.
     218                 :    * So the pixel at mBufferRotation within the buffer is what gets painted at
     219                 :    * mBufferRect.TopLeft().
     220                 :    * This is "rotation" in the sense of rotating items in a linear buffer,
     221                 :    * where items falling off the end of the buffer are returned to the
     222                 :    * buffer at the other end, not 2D rotation!
     223                 :    */
     224                 :   nsIntPoint            mBufferRotation;
     225                 :   BufferSizePolicy      mBufferSizePolicy;
     226                 : };
     227                 : 
     228                 : }
     229                 : }
     230                 : 
     231                 : #endif /* THEBESLAYERBUFFER_H_ */

Generated by: LCOV version 1.7