LCOV - app.info - objdir/dist/include/ImageLayers.h

LCOV - code coverage report
| Current view: | directory - objdir/dist/include - ImageLayers.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 29 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 15 | 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) 2009
          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 GFX_IMAGELAYER_H
          39                 : #define GFX_IMAGELAYER_H
          40                 :
          41                 : #include "Layers.h"
          42                 :
          43                 : #include "nsISupportsImpl.h"
          44                 : #include "gfxPattern.h"
          45                 : #include "nsThreadUtils.h"
          46                 : #include "mozilla/ReentrantMonitor.h"
          47                 : #include "mozilla/TimeStamp.h"
          48                 : #include "mozilla/mozalloc.h"
          49                 : #include "mozilla/Mutex.h"
          50                 : #include "gfxPlatform.h"
          51                 :
          52                 : #ifdef XP_MACOSX
          53                 : #include "nsIOSurface.h"
          54                 : #endif
          55                 :
          56                 : namespace mozilla {
          57                 :
          58                 : class CrossProcessMutex;
          59                 : namespace ipc {
          60                 : class Shmem;
          61                 : }
          62                 :
          63                 : namespace layers {
          64                 :
          65                 : enum StereoMode {
          66                 :   STEREO_MODE_MONO,
          67                 :   STEREO_MODE_LEFT_RIGHT,
          68                 :   STEREO_MODE_RIGHT_LEFT,
          69                 :   STEREO_MODE_BOTTOM_TOP,
          70                 :   STEREO_MODE_TOP_BOTTOM
          71                 : };
          72                 :
          73                 : struct ImageBackendData
          74                 : {
          75                 :   virtual ~ImageBackendData() {}
          76                 :
          77                 : protected:
          78                 :   ImageBackendData() {}
          79                 : };
          80                 :
          81                 : /**
          82                 :  * A class representing a buffer of pixel data. The data can be in one
          83                 :  * of various formats including YCbCr.
          84                 :  *
          85                 :  * Create an image using an ImageContainer. Fill the image with data, and
          86                 :  * then call ImageContainer::SetImage to display it. An image must not be
          87                 :  * modified after calling SetImage. Image implementations do not need to
          88                 :  * perform locking; when filling an Image, the Image client is responsible
          89                 :  * for ensuring only one thread accesses the Image at a time, and after
          90                 :  * SetImage the image is immutable.
          91                 :  *
          92                 :  * When resampling an Image, only pixels within the buffer should be
          93                 :  * sampled. For example, cairo images should be sampled in EXTEND_PAD mode.
          94                 :  */
          95                 : class THEBES_API Image {
          96               0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Image)
          97                 :
          98                 : public:
          99                 :   virtual ~Image() {}
         100                 :
         101                 :   enum Format {
         102                 :     /**
         103                 :      * The PLANAR_YCBCR format creates a PlanarYCbCrImage. All backends should
         104                 :      * support this format, because the Ogg video decoder depends on it.
         105                 :      * The maximum image width and height is 16384.
         106                 :      */
         107                 :     PLANAR_YCBCR,
         108                 :
         109                 :     /**
         110                 :      * The CAIRO_SURFACE format creates a CairoImage. All backends should
         111                 :      * support this format, because video rendering sometimes requires it.
         112                 :      *
         113                 :      * This format is useful even though a ThebesLayer could be used.
         114                 :      * It makes it easy to render a cairo surface when another Image format
         115                 :      * could be used. It can also avoid copying the surface data in some
         116                 :      * cases.
         117                 :      *
         118                 :      * Images in CAIRO_SURFACE format should only be created and
         119                 :      * manipulated on the main thread, since the underlying cairo surface
         120                 :      * is main-thread-only.
         121                 :      */
         122                 :     CAIRO_SURFACE,
         123                 :
         124                 :     /**
         125                 :      * The MAC_IO_SURFACE format creates a MacIOSurfaceImage.
         126                 :      *
         127                 :      * It wraps an IOSurface object and binds it directly to a GL texture.
         128                 :      */
         129                 :     MAC_IO_SURFACE,
         130                 :
         131                 :     /**
         132                 :      * An bitmap image that can be shared with a remote process.
         133                 :      */
         134                 :     REMOTE_IMAGE_BITMAP
         135                 :   };
         136                 :
         137               0 :   Format GetFormat() { return mFormat; }
         138                 :   void* GetImplData() { return mImplData; }
         139                 :
         140                 :   virtual already_AddRefed<gfxASurface> GetAsSurface() = 0;
         141                 :   virtual gfxIntSize GetSize() = 0;
         142                 :
         143                 :   ImageBackendData* GetBackendData(LayerManager::LayersBackend aBackend)
         144                 :   { return mBackendData[aBackend]; }
         145                 :   void SetBackendData(LayerManager::LayersBackend aBackend, ImageBackendData* aData)
         146                 :   { mBackendData[aBackend] = aData; }
         147                 :
         148                 : protected:
         149                 :   Image(void* aImplData, Format aFormat) :
         150                 :     mImplData(aImplData),
         151                 :     mFormat(aFormat)
         152                 :   {}
         153                 :
         154                 :   nsAutoPtr<ImageBackendData> mBackendData[LayerManager::LAYERS_LAST];
         155                 :
         156                 :   void* mImplData;
         157                 :   Format mFormat;
         158                 : };
         159                 :
         160                 : /**
         161                 :  * A RecycleBin is owned by an ImageContainer. We store buffers in it that we
         162                 :  * want to recycle from one image to the next.It's a separate object from
         163                 :  * ImageContainer because images need to store a strong ref to their RecycleBin
         164                 :  * and we must avoid creating a reference loop between an ImageContainer and
         165                 :  * its active image.
         166                 :  */
         167                 : class BufferRecycleBin {
         168                 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RecycleBin)
         169                 :
         170                 :   typedef mozilla::gl::GLContext GLContext;
         171                 :
         172                 : public:
         173                 :   BufferRecycleBin();
         174                 :
         175                 :   void RecycleBuffer(PRUint8* aBuffer, PRUint32 aSize);
         176                 :   // Returns a recycled buffer of the right size, or allocates a new buffer.
         177                 :   PRUint8* GetBuffer(PRUint32 aSize);
         178                 :
         179                 : private:
         180                 :   typedef mozilla::Mutex Mutex;
         181                 :
         182                 :   // This protects mRecycledBuffers, mRecycledBufferSize, mRecycledTextures
         183                 :   // and mRecycledTextureSizes
         184                 :   Mutex mLock;
         185                 :
         186                 :   // We should probably do something to prune this list on a timer so we don't
         187                 :   // eat excess memory while video is paused...
         188                 :   nsTArray<nsAutoArrayPtr<PRUint8> > mRecycledBuffers;
         189                 :   // This is only valid if mRecycledBuffers is non-empty
         190                 :   PRUint32 mRecycledBufferSize;
         191                 : };
         192                 :
         193                 : /**
         194                 :  * Returns true if aFormat is in the given format array.
         195                 :  */
         196                 : static inline bool
         197                 : FormatInList(const Image::Format* aFormats, PRUint32 aNumFormats,
         198                 :              Image::Format aFormat)
         199                 : {
         200                 :   for (PRUint32 i = 0; i < aNumFormats; ++i) {
         201                 :     if (aFormats[i] == aFormat) {
         202                 :       return true;
         203                 :     }
         204                 :   }
         205                 :   return false;
         206                 : }
         207                 :
         208                 : class CompositionNotifySink
         209               0 : {
         210                 : public:
         211                 :   virtual void DidComposite() = 0;
         212                 : };
         213                 :
         214                 : /**
         215                 :  * A class that manages Image creation for a LayerManager. The only reason
         216                 :  * we need a separate class here is that LayerMananers aren't threadsafe
         217                 :  * (because layers can only be used on the main thread) and we want to
         218                 :  * be able to create images from any thread, to facilitate video playback
         219                 :  * without involving the main thread, for example.
         220                 :  * Different layer managers can implement child classes of this making it
         221                 :  * possible to create layer manager specific images.
         222                 :  * This class is not meant to be used directly but rather can be set on an
         223                 :  * image container. This is usually done by the layer system internally and
         224                 :  * not explicitly by users. For PlanarYCbCr or Cairo images the default
         225                 :  * implementation will creates images whose data lives in system memory, for
         226                 :  * MacIOSurfaces the default implementation will be a simple nsIOSurface
         227                 :  * wrapper.
         228                 :  */
         229                 :
         230                 : class THEBES_API ImageFactory
         231                 : {
         232                 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageFactory)
         233                 : protected:
         234                 :   friend class ImageContainer;
         235                 :
         236                 :   ImageFactory() {}
         237                 :   virtual ~ImageFactory() {}
         238                 :
         239                 :   virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
         240                 :                                               PRUint32 aNumFormats,
         241                 :                                               const gfxIntSize &aScaleHint,
         242                 :                                               BufferRecycleBin *aRecycleBin);
         243                 :
         244                 : };
         245                 :
         246                 : /**
         247                 :  * This struct is used to store RemoteImages, it is meant to be able to live in
         248                 :  * shared memory. Therefor it should not contain a vtable pointer. Remote
         249                 :  * users can manipulate the data in this structure to specify what image is to
         250                 :  * be drawn by the container. When accessing this data users should make sure
         251                 :  * the mutex synchronizing access to the structure is held!
         252                 :  */
         253                 : struct RemoteImageData {
         254                 :   enum Type {
         255                 :     /**
         256                 :      * This is a format that uses raw bitmap data.
         257                 :      */
         258                 :     RAW_BITMAP
         259                 :   };
         260                 :   /* These formats describe the format in the memory byte-order */
         261                 :   enum Format {
         262                 :     /* 8 bits per channel */
         263                 :     BGRA32,
         264                 :     /* 8 bits per channel, alpha channel is ignored */
         265                 :     BGRX32
         266                 :   };
         267                 :
         268                 :   // This should be set to true if a change was made so that the ImageContainer
         269                 :   // knows to throw out any cached RemoteImage objects.
         270                 :   bool mWasUpdated;
         271                 :   Type mType;
         272                 :   Format mFormat;
         273                 :   gfxIntSize mSize;
         274                 :   union {
         275                 :     struct {
         276                 :       /* This pointer is set by a remote process, however it will be set to
         277                 :        * the container process' address the memory of the raw bitmap resides
         278                 :        * at.
         279                 :        */
         280                 :       unsigned char *mData;
         281                 :       int mStride;
         282                 :     } mBitmap;
         283                 :   };
         284                 : };
         285                 :
         286                 : /**
         287                 :  * A class that manages Images for an ImageLayer. The only reason
         288                 :  * we need a separate class here is that ImageLayers aren't threadsafe
         289                 :  * (because layers can only be used on the main thread) and we want to
         290                 :  * be able to set the current Image from any thread, to facilitate
         291                 :  * video playback without involving the main thread, for example.
         292                 :  */
         293                 : class THEBES_API ImageContainer {
         294               0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer)
         295                 :
         296                 : public:
         297                 :   ImageContainer() :
         298                 :     mReentrantMonitor("ImageContainer.mReentrantMonitor"),
         299                 :     mPaintCount(0),
         300                 :     mPreviousImagePainted(false),
         301                 :     mImageFactory(new ImageFactory()),
         302                 :     mRecycleBin(new BufferRecycleBin()),
         303                 :     mRemoteData(nsnull),
         304                 :     mRemoteDataMutex(nsnull),
         305                 :     mCompositionNotifySink(nsnull)
         306                 :   {}
         307                 :
         308                 :   ~ImageContainer();
         309                 :
         310                 :   /**
         311                 :    * Create an Image in one of the given formats.
         312                 :    * Picks the "best" format from the list and creates an Image of that
         313                 :    * format.
         314                 :    * Returns null if this backend does not support any of the formats.
         315                 :    * Can be called on any thread. This method takes mReentrantMonitor
         316                 :    * when accessing thread-shared state.
         317                 :    */
         318                 :   already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
         319                 :                                       PRUint32 aNumFormats);
         320                 :
         321                 :   /**
         322                 :    * Set an Image as the current image to display. The Image must have
         323                 :    * been created by this ImageContainer.
         324                 :    * Can be called on any thread. This method takes mReentrantMonitor
         325                 :    * when accessing thread-shared state.
         326                 :    * aImage can be null. While it's null, nothing will be painted.
         327                 :    *
         328                 :    * The Image data must not be modified after this method is called!
         329                 :    *
         330                 :    * Implementations must call CurrentImageChanged() while holding
         331                 :    * mReentrantMonitor.
         332                 :    */
         333                 :   void SetCurrentImage(Image* aImage);
         334                 :
         335                 :   /**
         336                 :    * Returns if the container currently has an image.
         337                 :    * Can be called on any thread. This method takes mReentrantMonitor
         338                 :    * when accessing thread-shared state.
         339                 :    */
         340                 :   bool HasCurrentImage();
         341                 :
         342                 :   /**
         343                 :    * Lock the current Image.
         344                 :    * This has to add a reference since otherwise there are race conditions
         345                 :    * where the current image is destroyed before the caller can add
         346                 :    * a reference. This lock strictly guarantees the underlying image remains
         347                 :    * valid, it does not mean the current image cannot change.
         348                 :    * Can be called on any thread. This method will lock the cross-process
         349                 :    * mutex to ensure remote processes cannot alter underlying data. This call
         350                 :    * -must- be balanced by a call to UnlockCurrentImage and users should avoid
         351                 :    * holding the image locked for a long time.
         352                 :    */
         353                 :   already_AddRefed<Image> LockCurrentImage();
         354                 :
         355                 :   /**
         356                 :    * This call unlocks the image. For remote images releasing the cross-process
         357                 :    * mutex.
         358                 :    */
         359                 :   void UnlockCurrentImage();
         360                 :
         361                 :   /**
         362                 :    * Get the current image as a gfxASurface. This is useful for fallback
         363                 :    * rendering.
         364                 :    * This can only be called from the main thread, since cairo objects
         365                 :    * can only be used from the main thread.
         366                 :    * This is defined here and not on Image because it's possible (likely)
         367                 :    * that some backends will make an Image "ready to draw" only when it
         368                 :    * becomes the current image for an image container.
         369                 :    * Returns null if there is no current image.
         370                 :    * Returns the size in aSize.
         371                 :    * The returned surface will never be modified. The caller must not
         372                 :    * modify it.
         373                 :    * Can be called on any thread. This method takes mReentrantMonitor
         374                 :    * when accessing thread-shared state.
         375                 :    * If the current image is a remote image, that is, if it is an image that
         376                 :    * may be shared accross processes, calling this function will make
         377                 :    * a copy of the image data while holding the mRemoteDataMutex. If possible,
         378                 :    * the lock methods should be used to avoid the copy, however this should be
         379                 :    * avoided if the surface is required for a long period of time.
         380                 :    */
         381                 :   already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSizeResult);
         382                 :
         383                 :   /**
         384                 :    * This is similar to GetCurrentAsSurface, however this does not make a copy
         385                 :    * of the image data and requires the user to call UnlockCurrentImage when
         386                 :    * done with the image data. Once UnlockCurrentImage has been called the
         387                 :    * surface returned by this function is no longer valid! This works for any
         388                 :    * type of image. Optionally a pointer can be passed to receive the current
         389                 :    * image.
         390                 :    */
         391                 :   already_AddRefed<gfxASurface> LockCurrentAsSurface(gfxIntSize* aSizeResult,
         392                 :                                                      Image** aCurrentImage = nsnull);
         393                 :
         394                 :   /**
         395                 :    * Returns the size of the image in pixels.
         396                 :    * Can be called on any thread. This method takes mReentrantMonitor when accessing
         397                 :    * thread-shared state.
         398                 :    */
         399                 :   gfxIntSize GetCurrentSize();
         400                 :
         401                 :   /**
         402                 :    * Sets a size that the image is expected to be rendered at.
         403                 :    * This is a hint for image backends to optimize scaling.
         404                 :    * Default implementation in this class is to ignore the hint.
         405                 :    * Can be called on any thread. This method takes mReentrantMonitor
         406                 :    * when accessing thread-shared state.
         407                 :    */
         408               0 :   void SetScaleHint(const gfxIntSize& aScaleHint)
         409               0 :   { mScaleHint = aScaleHint; }
         410                 :
         411                 :   void SetImageFactory(ImageFactory *aFactory)
         412                 :   {
         413                 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
         414                 :     mImageFactory = aFactory ? aFactory : new ImageFactory();
         415                 :   }
         416                 :
         417                 :   /**
         418                 :    * Returns the time at which the currently contained image was first
         419                 :    * painted.  This is reset every time a new image is set as the current
         420                 :    * image.  Note this may return a null timestamp if the current image
         421                 :    * has not yet been painted.  Can be called from any thread.
         422                 :    */
         423               0 :   TimeStamp GetPaintTime() {
         424               0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
         425               0 :     return mPaintTime;
         426                 :   }
         427                 :
         428                 :   /**
         429                 :    * Returns the number of images which have been contained in this container
         430                 :    * and painted at least once.  Can be called from any thread.
         431                 :    */
         432               0 :   PRUint32 GetPaintCount() {
         433               0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
         434               0 :     return mPaintCount;
         435                 :   }
         436                 :
         437                 :   /**
         438                 :    * Increments mPaintCount if this is the first time aPainted has been
         439                 :    * painted, and sets mPaintTime if the painted image is the current image.
         440                 :    * current image.  Can be called from any thread.
         441                 :    */
         442                 :   void NotifyPaintedImage(Image* aPainted) {
         443                 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
         444                 :
         445                 :     nsRefPtr<Image> current = mActiveImage;
         446                 :     if (aPainted == current) {
         447                 :       if (mPaintTime.IsNull()) {
         448                 :         mPaintTime = TimeStamp::Now();
         449                 :         mPaintCount++;
         450                 :       }
         451                 :     } else if (!mPreviousImagePainted) {
         452                 :       // While we were painting this image, the current image changed. We
         453                 :       // still must count it as painted, but can't set mPaintTime, since we're
         454                 :       // no longer the current image.
         455                 :       mPaintCount++;
         456                 :       mPreviousImagePainted = true;
         457                 :     }
         458                 :
         459                 :     if (mCompositionNotifySink) {
         460                 :       mCompositionNotifySink->DidComposite();
         461                 :     }
         462                 :   }
         463                 :
         464               0 :   void SetCompositionNotifySink(CompositionNotifySink *aSink) {
         465               0 :     mCompositionNotifySink = aSink;
         466               0 :   }
         467                 :
         468                 :   /**
         469                 :    * This function is called to tell the ImageContainer where the
         470                 :    * (cross-process) segment lives where the shared data about possible
         471                 :    * remote images are stored. In addition to this a CrossProcessMutex object
         472                 :    * is passed telling the container how to synchronize access to this data.
         473                 :    * NOTE: This should be called during setup of the container and not after
         474                 :    * usage has started.
         475                 :    */
         476                 :   void SetRemoteImageData(RemoteImageData *aRemoteData,
         477                 :                           CrossProcessMutex *aRemoteDataMutex);
         478                 :   /**
         479                 :    * This can be used to check if the container has RemoteData set.
         480                 :    */
         481                 :   RemoteImageData *GetRemoteImageData() { return mRemoteData; }
         482                 :
         483                 : protected:
         484                 :   typedef mozilla::ReentrantMonitor ReentrantMonitor;
         485                 :
         486                 :   // This is called to ensure we have an active image, this may not be true
         487                 :   // when we're storing image information in a RemoteImageData structure.
         488                 :   // NOTE: If we have remote data mRemoteDataMutex should be locked when
         489                 :   // calling this function!
         490                 :   void EnsureActiveImage();
         491                 :
         492                 :   // ReentrantMonitor to protect thread safe access to the "current
         493                 :   // image", and any other state which is shared between threads.
         494                 :   ReentrantMonitor mReentrantMonitor;
         495                 :
         496                 :   // Performs necessary housekeeping to ensure the painted frame statistics
         497                 :   // are accurate. Must be called by SetCurrentImage() implementations with
         498                 :   // mReentrantMonitor held.
         499                 :   void CurrentImageChanged() {
         500                 :     mReentrantMonitor.AssertCurrentThreadIn();
         501                 :     mPreviousImagePainted = !mPaintTime.IsNull();
         502                 :     mPaintTime = TimeStamp();
         503                 :   }
         504                 :
         505                 :   nsRefPtr<Image> mActiveImage;
         506                 :
         507                 :   // Number of contained images that have been painted at least once.  It's up
         508                 :   // to the ImageContainer implementation to ensure accesses to this are
         509                 :   // threadsafe.
         510                 :   PRUint32 mPaintCount;
         511                 :
         512                 :   // Time stamp at which the current image was first painted.  It's up to the
         513                 :   // ImageContainer implementation to ensure accesses to this are threadsafe.
         514                 :   TimeStamp mPaintTime;
         515                 :
         516                 :   // Denotes whether the previous image was painted.
         517                 :   bool mPreviousImagePainted;
         518                 :
         519                 :   // This is the image factory used by this container, layer managers using
         520                 :   // this container can set an alternative image factory that will be used to
         521                 :   // create images for this container.
         522                 :   nsRefPtr<ImageFactory> mImageFactory;
         523                 :
         524                 :   gfxIntSize mScaleHint;
         525                 :
         526                 :   nsRefPtr<BufferRecycleBin> mRecycleBin;
         527                 :
         528                 :   // This contains the remote image data for this container, if this is NULL
         529                 :   // that means the container has no other process that may control its active
         530                 :   // image.
         531                 :   RemoteImageData *mRemoteData;
         532                 :
         533                 :   // This cross-process mutex is used to synchronise access to mRemoteData.
         534                 :   // When this mutex is held, we will always be inside the mReentrantMonitor
         535                 :   // however the same is not true vice versa.
         536                 :   CrossProcessMutex *mRemoteDataMutex;
         537                 :
         538                 :   CompositionNotifySink *mCompositionNotifySink;
         539                 : };
         540                 :
         541                 : class AutoLockImage
         542                 : {
         543                 : public:
         544                 :   AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
         545                 :   AutoLockImage(ImageContainer *aContainer, gfxASurface **aSurface) : mContainer(aContainer) {
         546                 :     *aSurface = mContainer->LockCurrentAsSurface(&mSize, getter_AddRefs(mImage)).get();
         547                 :   }
         548                 :   ~AutoLockImage() { if (mContainer) { mContainer->UnlockCurrentImage(); } }
         549                 :
         550                 :   Image* GetImage() { return mImage; }
         551                 :   const gfxIntSize &GetSize() { return mSize; }
         552                 :
         553                 :   void Unlock() {
         554                 :     if (mContainer) {
         555                 :       mImage = nsnull;
         556                 :       mContainer->UnlockCurrentImage();
         557                 :       mContainer = nsnull;
         558                 :     }
         559                 :   }
         560                 :
         561                 :   /** Things get a little tricky here, because our underlying image can -still-
         562                 :    * change, and OS X requires a complicated callback mechanism to update this
         563                 :    * we need to support staying the lock and getting the new image in a proper
         564                 :    * way. This method makes any images retrieved with GetImage invalid!
         565                 :    */
         566                 :   void Refresh() {
         567                 :     if (mContainer) {
         568                 :       mContainer->UnlockCurrentImage();
         569                 :       mImage = mContainer->LockCurrentImage();
         570                 :     }
         571                 :   }
         572                 :
         573                 : private:
         574                 :   ImageContainer *mContainer;
         575                 :   nsRefPtr<Image> mImage;
         576                 :   gfxIntSize mSize;
         577                 : };
         578                 :
         579                 : /**
         580                 :  * A Layer which renders an Image.
         581                 :  */
         582                 : class THEBES_API ImageLayer : public Layer {
         583                 : public:
         584                 :   enum ScaleMode {
         585                 :     SCALE_NONE,
         586                 :     SCALE_STRETCH // Unimplemented on GL layers and e10s
         587                 :   // Unimplemented - SCALE_PRESERVE_ASPECT_RATIO_CONTAIN
         588                 :   };
         589                 :
         590                 :   /**
         591                 :    * CONSTRUCTION PHASE ONLY
         592                 :    * Set the ImageContainer. aContainer must have the same layer manager
         593                 :    * as this layer.
         594                 :    */
         595               0 :   void SetContainer(ImageContainer* aContainer)
         596                 :   {
         597               0 :     mContainer = aContainer;
         598               0 :   }
         599                 :   /**
         600                 :    * CONSTRUCTION PHASE ONLY
         601                 :    * Set the filter used to resample this image if necessary.
         602                 :    */
         603               0 :   void SetFilter(gfxPattern::GraphicsFilter aFilter) { mFilter = aFilter; }
         604                 :
         605                 :   /**
         606                 :    * CONSTRUCTION PHASE ONLY
         607                 :    * Set the size to scale the image to and the mode at which to scale.
         608                 :    */
         609               0 :   void SetScaleToSize(const gfxIntSize &aSize, ScaleMode aMode)
         610                 :   {
         611               0 :     mScaleToSize = aSize;
         612               0 :     mScaleMode = aMode;
         613               0 :   }
         614                 :
         615                 :
         616                 :   ImageContainer* GetContainer() { return mContainer; }
         617                 :   gfxPattern::GraphicsFilter GetFilter() { return mFilter; }
         618                 :
         619                 :   MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE)
         620                 :
         621                 :   virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
         622                 :   {
         623                 :     // Snap image edges to pixel boundaries
         624                 :     gfxRect snap(0, 0, 0, 0);
         625                 :     if (mContainer) {
         626                 :       gfxIntSize size = mContainer->GetCurrentSize();
         627                 :       snap.SizeTo(gfxSize(size.width, size.height));
         628                 :     }
         629                 :     // Snap our local transform first, and snap the inherited transform as well.
         630                 :     // This makes our snapping equivalent to what would happen if our content
         631                 :     // was drawn into a ThebesLayer (gfxContext would snap using the local
         632                 :     // transform, then we'd snap again when compositing the ThebesLayer).
         633                 :     mEffectiveTransform =
         634                 :         SnapTransform(GetLocalTransform(), snap, nsnull)*
         635                 :         SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nsnull);
         636                 :   }
         637                 :
         638                 : protected:
         639                 :   ImageLayer(LayerManager* aManager, void* aImplData)
         640                 :     : Layer(aManager, aImplData), mFilter(gfxPattern::FILTER_GOOD)
         641                 :     , mScaleMode(SCALE_NONE) {}
         642                 :
         643                 :   virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
         644                 :
         645                 :
         646                 :   nsRefPtr<ImageContainer> mContainer;
         647                 :   gfxPattern::GraphicsFilter mFilter;
         648                 :   gfxIntSize mScaleToSize;
         649                 :   ScaleMode mScaleMode;
         650                 : };
         651                 :
         652                 : /****** Image subtypes for the different formats ******/
         653                 :
         654                 : /**
         655                 :  * We assume that the image data is in the REC 470M color space (see
         656                 :  * Theora specification, section 4.3.1).
         657                 :  *
         658                 :  * The YCbCr format can be:
         659                 :  *
         660                 :  * 4:4:4 - CbCr width/height are the same as Y.
         661                 :  * 4:2:2 - CbCr width is half that of Y. Height is the same.
         662                 :  * 4:2:0 - CbCr width and height is half that of Y.
         663                 :  *
         664                 :  * The color format is detected based on the height/width ratios
         665                 :  * defined above.
         666                 :  *
         667                 :  * The Image that is rendered is the picture region defined by
         668                 :  * mPicX, mPicY and mPicSize. The size of the rendered image is
         669                 :  * mPicSize, not mYSize or mCbCrSize.
         670                 :  */
         671                 : class THEBES_API PlanarYCbCrImage : public Image {
         672                 : public:
         673               0 :   struct Data {
         674                 :     // Luminance buffer
         675                 :     PRUint8* mYChannel;
         676                 :     PRInt32 mYStride;
         677                 :     gfxIntSize mYSize;
         678                 :     // Chroma buffers
         679                 :     PRUint8* mCbChannel;
         680                 :     PRUint8* mCrChannel;
         681                 :     PRInt32 mCbCrStride;
         682                 :     gfxIntSize mCbCrSize;
         683                 :     // Picture region
         684                 :     PRUint32 mPicX;
         685                 :     PRUint32 mPicY;
         686                 :     gfxIntSize mPicSize;
         687                 :     StereoMode mStereoMode;
         688                 :
         689                 :     nsIntRect GetPictureRect() const {
         690                 :       return nsIntRect(mPicX, mPicY,
         691                 :                        mPicSize.width,
         692                 :                        mPicSize.height);
         693                 :     }
         694                 :   };
         695                 :
         696                 :   enum {
         697                 :     MAX_DIMENSION = 16384
         698                 :   };
         699                 :
         700                 :   ~PlanarYCbCrImage();
         701                 :
         702                 :   /**
         703                 :    * This makes a copy of the data buffers, in order to support functioning
         704                 :    * in all different layer managers.
         705                 :    */
         706                 :   virtual void SetData(const Data& aData);
         707                 :
         708                 :   /**
         709                 :    * Ask this Image to not convert YUV to RGB during SetData, and make
         710                 :    * the original data available through GetData. This is optional,
         711                 :    * and not all PlanarYCbCrImages will support it.
         712                 :    */
         713                 :   virtual void SetDelayedConversion(bool aDelayed) { }
         714                 :
         715                 :   /**
         716                 :    * Grab the original YUV data. This is optional.
         717                 :    */
         718                 :   virtual const Data* GetData() { return &mData; }
         719                 :
         720                 :   /**
         721                 :    * Make a copy of the YCbCr data into local storage.
         722                 :    *
         723                 :    * @param aData           Input image data.
         724                 :    */
         725                 :   void CopyData(const Data& aData);
         726                 :
         727                 :   /**
         728                 :    * Return a buffer to store image data in.
         729                 :    * The default implementation returns memory that can
         730                 :    * be freed wit delete[]
         731                 :    */
         732                 :   virtual PRUint8* AllocateBuffer(PRUint32 aSize);
         733                 :
         734                 :   /**
         735                 :    * Return the number of bytes of heap memory used to store this image.
         736                 :    */
         737                 :   virtual PRUint32 GetDataSize() { return mBufferSize; }
         738                 :
         739                 :   already_AddRefed<gfxASurface> GetAsSurface();
         740                 :
         741                 :   virtual gfxIntSize GetSize() { return mSize; }
         742                 :
         743                 :   void SetOffscreenFormat(gfxImageFormat aFormat) { mOffscreenFormat = aFormat; }
         744                 :   gfxImageFormat GetOffscreenFormat() { return mOffscreenFormat; }
         745                 :
         746                 :   // XXX - not easy to protect these sadly.
         747                 :   nsAutoArrayPtr<PRUint8> mBuffer;
         748                 :   PRUint32 mBufferSize;
         749                 :   Data mData;
         750                 :   gfxIntSize mSize;
         751                 :   gfxImageFormat mOffscreenFormat;
         752                 :   nsCountedRef<nsMainThreadSurfaceRef> mSurface;
         753                 :   nsRefPtr<BufferRecycleBin> mRecycleBin;
         754                 :
         755                 :   PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
         756                 : };
         757                 :
         758                 : /**
         759                 :  * Currently, the data in a CairoImage surface is treated as being in the
         760                 :  * device output color space. This class is very simple as all backends
         761                 :  * have to know about how to deal with drawing a cairo image.
         762                 :  */
         763                 : class THEBES_API CairoImage : public Image {
         764                 : public:
         765               0 :   struct Data {
         766                 :     gfxASurface* mSurface;
         767                 :     gfxIntSize mSize;
         768                 :   };
         769                 :
         770                 :   /**
         771                 :    * This can only be called on the main thread. It may add a reference
         772                 :    * to the surface (which will eventually be released on the main thread).
         773                 :    * The surface must not be modified after this call!!!
         774                 :    */
         775               0 :   void SetData(const Data& aData)
         776                 :   {
         777               0 :     mSurface = aData.mSurface;
         778               0 :     mSize = aData.mSize;
         779               0 :   }
         780                 :
         781                 :
         782                 :   virtual already_AddRefed<gfxASurface> GetAsSurface()
         783                 :   {
         784                 :     NS_ASSERTION(NS_IsMainThread(), "Must be main thread");
         785                 :     nsRefPtr<gfxASurface> surface = mSurface.get();
         786                 :     return surface.forget();
         787                 :   }
         788                 :
         789                 :   gfxIntSize GetSize() { return mSize; }
         790                 :
         791                 :   CairoImage() : Image(NULL, CAIRO_SURFACE) {}
         792                 :
         793                 :   nsCountedRef<nsMainThreadSurfaceRef> mSurface;
         794                 :   gfxIntSize mSize;
         795                 : };
         796                 :
         797                 : #ifdef XP_MACOSX
         798                 : class THEBES_API MacIOSurfaceImage : public Image {
         799                 : public:
         800                 :   struct Data {
         801                 :     nsIOSurface* mIOSurface;
         802                 :   };
         803                 :
         804                 :   MacIOSurfaceImage()
         805                 :     : Image(NULL, MAC_IO_SURFACE)
         806                 :     , mSize(0, 0)
         807                 :     , mPluginInstanceOwner(NULL)
         808                 :     , mUpdateCallback(NULL)
         809                 :     , mDestroyCallback(NULL)
         810                 :     {}
         811                 :
         812                 :   virtual ~MacIOSurfaceImage()
         813                 :   {
         814                 :     if (mDestroyCallback) {
         815                 :       mDestroyCallback(mPluginInstanceOwner);
         816                 :     }
         817                 :   }
         818                 :
         819                 :  /**
         820                 :   * This can only be called on the main thread. It may add a reference
         821                 :   * to the surface (which will eventually be released on the main thread).
         822                 :   * The surface must not be modified after this call!!!
         823                 :   */
         824                 :   virtual void SetData(const Data& aData);
         825                 :
         826                 :   /**
         827                 :    * Temporary hacks to force plugin drawing during an empty transaction.
         828                 :    * This should not be used for anything else, and will be removed
         829                 :    * when async plugin rendering is complete.
         830                 :    */
         831                 :   typedef void (*UpdateSurfaceCallback)(ImageContainer* aContainer, void* aInstanceOwner);
         832                 :   virtual void SetUpdateCallback(UpdateSurfaceCallback aCallback, void* aInstanceOwner)
         833                 :   {
         834                 :     mUpdateCallback = aCallback;
         835                 :     mPluginInstanceOwner = aInstanceOwner;
         836                 :   }
         837                 :
         838                 :   typedef void (*DestroyCallback)(void* aInstanceOwner);
         839                 :   virtual void SetDestroyCallback(DestroyCallback aCallback)
         840                 :   {
         841                 :     mDestroyCallback = aCallback;
         842                 :   }
         843                 :
         844                 :   virtual gfxIntSize GetSize()
         845                 :   {
         846                 :     return mSize;
         847                 :   }
         848                 :
         849                 :   nsIOSurface* GetIOSurface()
         850                 :   {
         851                 :     return mIOSurface;
         852                 :   }
         853                 :
         854                 :   void Update(ImageContainer* aContainer);
         855                 :
         856                 :   virtual already_AddRefed<gfxASurface> GetAsSurface();
         857                 :
         858                 : private:
         859                 :   gfxIntSize mSize;
         860                 :   nsRefPtr<nsIOSurface> mIOSurface;
         861                 :   void* mPluginInstanceOwner;
         862                 :   UpdateSurfaceCallback mUpdateCallback;
         863                 :   DestroyCallback mDestroyCallback;
         864                 : };
         865                 : #endif
         866                 :
         867                 : class RemoteBitmapImage : public Image {
         868                 : public:
         869                 :   RemoteBitmapImage() : Image(NULL, REMOTE_IMAGE_BITMAP) {}
         870                 :
         871                 :   already_AddRefed<gfxASurface> GetAsSurface();
         872                 :
         873                 :   gfxIntSize GetSize() { return mSize; }
         874                 :
         875                 :   unsigned char *mData;
         876                 :   int mStride;
         877                 :   gfxIntSize mSize;
         878                 :   RemoteImageData::Format mFormat;
         879                 : };
         880                 :
         881                 : }
         882                 : }
         883                 :
         884                 : #endif /* GFX_IMAGELAYER_H */

Generated by: LCOV version 1.7