Bumping manifests a=b2g-bump
[gecko.git] / gfx / layers / ImageContainer.h
blobf106b56684f42c905fd9e64087b6d4c606e9afcf
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef GFX_IMAGECONTAINER_H
7 #define GFX_IMAGECONTAINER_H
9 #include <stdint.h> // for uint32_t, uint8_t, uint64_t
10 #include <sys/types.h> // for int32_t
11 #include "gfxTypes.h"
12 #include "ImageTypes.h" // for ImageFormat, etc
13 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
14 #include "mozilla/Mutex.h" // for Mutex
15 #include "mozilla/ReentrantMonitor.h" // for ReentrantMonitorAutoEnter, etc
16 #include "mozilla/TimeStamp.h" // for TimeStamp
17 #include "mozilla/gfx/Point.h" // For IntSize
18 #include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc
19 #include "mozilla/mozalloc.h" // for operator delete, etc
20 #include "nsAutoPtr.h" // for nsRefPtr, nsAutoArrayPtr, etc
21 #include "nsAutoRef.h" // for nsCountedRef
22 #include "nsCOMPtr.h" // for already_AddRefed
23 #include "nsDebug.h" // for NS_ASSERTION
24 #include "nsISupportsImpl.h" // for Image::Release, etc
25 #include "nsRect.h" // for nsIntRect
26 #include "nsSize.h" // for nsIntSize
27 #include "nsTArray.h" // for nsTArray
28 #include "mozilla/Atomics.h"
29 #include "mozilla/WeakPtr.h"
30 #include "nsThreadUtils.h"
31 #include "mozilla/gfx/2D.h"
32 #include "nsDataHashtable.h"
33 #include "mozilla/EnumeratedArray.h"
35 #ifndef XPCOM_GLUE_AVOID_NSPR
36 /**
37 * We need to be able to hold a reference to a Moz2D SourceSurface from Image
38 * subclasses. This is potentially a problem since Images can be addrefed
39 * or released off the main thread. We can ensure that we never AddRef
40 * a SourceSurface off the main thread, but we might want to Release due
41 * to an Image being destroyed off the main thread.
43 * We use nsCountedRef<nsMainThreadSourceSurfaceRef> to reference the
44 * SourceSurface. When AddRefing, we assert that we're on the main thread.
45 * When Releasing, if we're not on the main thread, we post an event to
46 * the main thread to do the actual release.
48 class nsMainThreadSourceSurfaceRef;
50 template <>
51 class nsAutoRefTraits<nsMainThreadSourceSurfaceRef> {
52 public:
53 typedef mozilla::gfx::SourceSurface* RawRef;
55 /**
56 * The XPCOM event that will do the actual release on the main thread.
58 class SurfaceReleaser : public nsRunnable {
59 public:
60 explicit SurfaceReleaser(RawRef aRef) : mRef(aRef) {}
61 NS_IMETHOD Run() {
62 mRef->Release();
63 return NS_OK;
65 RawRef mRef;
68 static RawRef Void() { return nullptr; }
69 static void Release(RawRef aRawRef)
71 if (NS_IsMainThread()) {
72 aRawRef->Release();
73 return;
75 nsCOMPtr<nsIRunnable> runnable = new SurfaceReleaser(aRawRef);
76 NS_DispatchToMainThread(runnable);
78 static void AddRef(RawRef aRawRef)
80 NS_ASSERTION(NS_IsMainThread(),
81 "Can only add a reference on the main thread");
82 aRawRef->AddRef();
86 #endif
88 #ifdef XP_WIN
89 struct ID3D10Texture2D;
90 struct ID3D10Device;
91 struct ID3D10ShaderResourceView;
92 #endif
94 typedef void* HANDLE;
96 namespace mozilla {
98 class CrossProcessMutex;
100 namespace layers {
102 class ImageClient;
103 class SharedPlanarYCbCrImage;
104 class TextureClient;
105 class CompositableClient;
106 class CompositableForwarder;
107 class SurfaceDescriptor;
108 class GrallocImage;
110 struct ImageBackendData
112 virtual ~ImageBackendData() {}
114 protected:
115 ImageBackendData() {}
119 * A class representing a buffer of pixel data. The data can be in one
120 * of various formats including YCbCr.
122 * Create an image using an ImageContainer. Fill the image with data, and
123 * then call ImageContainer::SetImage to display it. An image must not be
124 * modified after calling SetImage. Image implementations do not need to
125 * perform locking; when filling an Image, the Image client is responsible
126 * for ensuring only one thread accesses the Image at a time, and after
127 * SetImage the image is immutable.
129 * When resampling an Image, only pixels within the buffer should be
130 * sampled. For example, cairo images should be sampled in EXTEND_PAD mode.
132 class Image {
133 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Image)
135 public:
136 ImageFormat GetFormat() { return mFormat; }
137 void* GetImplData() { return mImplData; }
139 virtual gfx::IntSize GetSize() = 0;
140 virtual nsIntRect GetPictureRect()
142 return nsIntRect(0, 0, GetSize().width, GetSize().height);
145 ImageBackendData* GetBackendData(LayersBackend aBackend)
146 { return mBackendData[aBackend]; }
147 void SetBackendData(LayersBackend aBackend, ImageBackendData* aData)
148 { mBackendData[aBackend] = aData; }
150 int32_t GetSerial() { return mSerial; }
152 void MarkSent() { mSent = true; }
153 bool IsSentToCompositor() { return mSent; }
155 virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() = 0;
157 virtual GrallocImage* AsGrallocImage()
159 return nullptr;
162 virtual bool IsValid() { return true; }
164 virtual uint8_t* GetBuffer() { return nullptr; }
167 * For use with the CompositableClient only (so that the later can
168 * synchronize the TextureClient with the TextureHost).
170 virtual TextureClient* GetTextureClient(CompositableClient* aClient) { return nullptr; }
172 protected:
173 Image(void* aImplData, ImageFormat aFormat) :
174 mImplData(aImplData),
175 mSerial(++sSerialCounter),
176 mFormat(aFormat),
177 mSent(false)
180 // Protected destructor, to discourage deletion outside of Release():
181 virtual ~Image() {}
183 mozilla::EnumeratedArray<mozilla::layers::LayersBackend,
184 mozilla::layers::LayersBackend::LAYERS_LAST,
185 nsAutoPtr<ImageBackendData>>
186 mBackendData;
188 void* mImplData;
189 int32_t mSerial;
190 ImageFormat mFormat;
191 static mozilla::Atomic<int32_t> sSerialCounter;
192 bool mSent;
196 * A RecycleBin is owned by an ImageContainer. We store buffers in it that we
197 * want to recycle from one image to the next.It's a separate object from
198 * ImageContainer because images need to store a strong ref to their RecycleBin
199 * and we must avoid creating a reference loop between an ImageContainer and
200 * its active image.
202 class BufferRecycleBin MOZ_FINAL {
203 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BufferRecycleBin)
205 //typedef mozilla::gl::GLContext GLContext;
207 public:
208 BufferRecycleBin();
210 void RecycleBuffer(uint8_t* aBuffer, uint32_t aSize);
211 // Returns a recycled buffer of the right size, or allocates a new buffer.
212 uint8_t* GetBuffer(uint32_t aSize);
214 private:
215 typedef mozilla::Mutex Mutex;
217 // Private destructor, to discourage deletion outside of Release():
218 ~BufferRecycleBin()
222 // This protects mRecycledBuffers, mRecycledBufferSize, mRecycledTextures
223 // and mRecycledTextureSizes
224 Mutex mLock;
226 // We should probably do something to prune this list on a timer so we don't
227 // eat excess memory while video is paused...
228 nsTArray<nsAutoArrayPtr<uint8_t> > mRecycledBuffers;
229 // This is only valid if mRecycledBuffers is non-empty
230 uint32_t mRecycledBufferSize;
233 class CompositionNotifySink
235 public:
236 virtual void DidComposite() = 0;
237 virtual ~CompositionNotifySink() {}
241 * A class that manages Image creation for a LayerManager. The only reason
242 * we need a separate class here is that LayerManagers aren't threadsafe
243 * (because layers can only be used on the main thread) and we want to
244 * be able to create images from any thread, to facilitate video playback
245 * without involving the main thread, for example.
246 * Different layer managers can implement child classes of this making it
247 * possible to create layer manager specific images.
248 * This class is not meant to be used directly but rather can be set on an
249 * image container. This is usually done by the layer system internally and
250 * not explicitly by users. For PlanarYCbCr or Cairo images the default
251 * implementation will creates images whose data lives in system memory, for
252 * MacIOSurfaces the default implementation will be a simple MacIOSurface
253 * wrapper.
256 class ImageFactory
258 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageFactory)
259 protected:
260 friend class ImageContainer;
262 ImageFactory() {}
263 virtual ~ImageFactory() {}
265 virtual already_AddRefed<Image> CreateImage(ImageFormat aFormat,
266 const gfx::IntSize &aScaleHint,
267 BufferRecycleBin *aRecycleBin);
272 * A class that manages Images for an ImageLayer. The only reason
273 * we need a separate class here is that ImageLayers aren't threadsafe
274 * (because layers can only be used on the main thread) and we want to
275 * be able to set the current Image from any thread, to facilitate
276 * video playback without involving the main thread, for example.
278 * An ImageContainer can operate in one of these modes:
279 * 1) Normal. Triggered by constructing the ImageContainer with
280 * DISABLE_ASYNC or when compositing is happening on the main thread.
281 * SetCurrentImage changes ImageContainer state but nothing is sent to the
282 * compositor until the next layer transaction.
283 * 2) Asynchronous. Initiated by constructing the ImageContainer with
284 * ENABLE_ASYNC when compositing is happening on the main thread.
285 * SetCurrentImage sends a message through the ImageBridge to the compositor
286 * thread to update the image, without going through the main thread or
287 * a layer transaction.
288 * The ImageContainer uses a shared memory block containing a cross-process mutex
289 * to communicate with the compositor thread. SetCurrentImage synchronously
290 * updates the shared state to point to the new image and the old image
291 * is immediately released (not true in Normal or Asynchronous modes).
293 class ImageContainer MOZ_FINAL : public SupportsWeakPtr<ImageContainer> {
294 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer)
295 public:
296 MOZ_DECLARE_REFCOUNTED_TYPENAME(ImageContainer)
298 enum { DISABLE_ASYNC = 0x0, ENABLE_ASYNC = 0x01 };
300 explicit ImageContainer(int flag = 0);
303 * Create an Image in one of the given formats.
304 * Picks the "best" format from the list and creates an Image of that
305 * format.
306 * Returns null if this backend does not support any of the formats.
307 * Can be called on any thread. This method takes mReentrantMonitor
308 * when accessing thread-shared state.
310 B2G_ACL_EXPORT already_AddRefed<Image> CreateImage(ImageFormat aFormat);
313 * Set an Image as the current image to display. The Image must have
314 * been created by this ImageContainer.
315 * Can be called on any thread. This method takes mReentrantMonitor
316 * when accessing thread-shared state.
317 * aImage can be null. While it's null, nothing will be painted.
319 * The Image data must not be modified after this method is called!
320 * Note that this must not be called if ENABLE_ASYNC has not been set.
322 * Implementations must call CurrentImageChanged() while holding
323 * mReentrantMonitor.
325 * If this ImageContainer has an ImageClient for async video:
326 * Schelude a task to send the image to the compositor using the
327 * PImageBridge protcol without using the main thread.
329 void SetCurrentImage(Image* aImage);
332 * Clear all images. Let ImageClient release all TextureClients.
334 void ClearAllImages();
337 * Clear all images except current one.
338 * Let ImageClient release all TextureClients except front one.
340 void ClearAllImagesExceptFront();
343 * Clear the current image.
344 * This function is expect to be called only from a CompositableClient
345 * that belongs to ImageBridgeChild. Created to prevent dead lock.
346 * See Bug 901224.
348 void ClearCurrentImage();
351 * Set an Image as the current image to display. The Image must have
352 * been created by this ImageContainer.
353 * Must be called on the main thread, within a layers transaction.
355 * This method takes mReentrantMonitor
356 * when accessing thread-shared state.
357 * aImage can be null. While it's null, nothing will be painted.
359 * The Image data must not be modified after this method is called!
360 * Note that this must not be called if ENABLE_ASYNC been set.
362 * Implementations must call CurrentImageChanged() while holding
363 * mReentrantMonitor.
365 void SetCurrentImageInTransaction(Image* aImage);
368 * Returns true if this ImageContainer uses the ImageBridge IPDL protocol.
370 * Can be called from any thread.
372 bool IsAsync() const;
375 * If this ImageContainer uses ImageBridge, returns the ID associated to
376 * this container, for use in the ImageBridge protocol.
377 * Returns 0 if this ImageContainer does not use ImageBridge. Note that
378 * 0 is always an invalid ID for asynchronous image containers.
380 * Can be called from any thread.
382 uint64_t GetAsyncContainerID() const;
385 * Returns if the container currently has an image.
386 * Can be called on any thread. This method takes mReentrantMonitor
387 * when accessing thread-shared state.
389 bool HasCurrentImage();
392 * Lock the current Image.
393 * This has to add a reference since otherwise there are race conditions
394 * where the current image is destroyed before the caller can add
395 * a reference. This lock strictly guarantees the underlying image remains
396 * valid, it does not mean the current image cannot change.
397 * Can be called on any thread. This method will lock the cross-process
398 * mutex to ensure remote processes cannot alter underlying data. This call
399 * -must- be balanced by a call to UnlockCurrentImage and users should avoid
400 * holding the image locked for a long time.
402 already_AddRefed<Image> LockCurrentImage();
405 * This call unlocks the image. For remote images releasing the cross-process
406 * mutex.
408 void UnlockCurrentImage();
411 * Get the current image as a SourceSurface. This is useful for fallback
412 * rendering.
413 * This can only be called from the main thread, since cairo objects
414 * can only be used from the main thread.
415 * This is defined here and not on Image because it's possible (likely)
416 * that some backends will make an Image "ready to draw" only when it
417 * becomes the current image for an image container.
418 * Returns null if there is no current image.
419 * Returns the size in aSize.
420 * The returned surface will never be modified. The caller must not
421 * modify it.
422 * Can be called on any thread. This method takes mReentrantMonitor
423 * when accessing thread-shared state.
424 * If the current image is a remote image, that is, if it is an image that
425 * may be shared accross processes, calling this function will make
426 * a copy of the image data while holding the mRemoteDataMutex. If possible,
427 * the lock methods should be used to avoid the copy, however this should be
428 * avoided if the surface is required for a long period of time.
430 TemporaryRef<gfx::SourceSurface> GetCurrentAsSourceSurface(gfx::IntSize* aSizeResult);
433 * Same as LockCurrentAsSurface but for Moz2D
435 TemporaryRef<gfx::SourceSurface> LockCurrentAsSourceSurface(gfx::IntSize* aSizeResult,
436 Image** aCurrentImage = nullptr);
439 * Returns the size of the image in pixels.
440 * Can be called on any thread. This method takes mReentrantMonitor when accessing
441 * thread-shared state.
443 gfx::IntSize GetCurrentSize();
446 * Sets a size that the image is expected to be rendered at.
447 * This is a hint for image backends to optimize scaling.
448 * Default implementation in this class is to ignore the hint.
449 * Can be called on any thread. This method takes mReentrantMonitor
450 * when accessing thread-shared state.
452 void SetScaleHint(const gfx::IntSize& aScaleHint)
453 { mScaleHint = aScaleHint; }
455 void SetImageFactory(ImageFactory *aFactory)
457 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
458 mImageFactory = aFactory ? aFactory : new ImageFactory();
461 ImageFactory* GetImageFactory() const
463 return mImageFactory;
467 * Returns the time at which the currently contained image was first
468 * painted. This is reset every time a new image is set as the current
469 * image. Note this may return a null timestamp if the current image
470 * has not yet been painted. Can be called from any thread.
472 TimeStamp GetPaintTime() {
473 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
474 return mPaintTime;
478 * Returns the number of images which have been contained in this container
479 * and painted at least once. Can be called from any thread.
481 uint32_t GetPaintCount() {
482 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
483 return mPaintCount;
487 * Resets the paint count to zero.
488 * Can be called from any thread.
490 void ResetPaintCount() {
491 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
492 mPaintCount = 0;
496 * Increments mPaintCount if this is the first time aPainted has been
497 * painted, and sets mPaintTime if the painted image is the current image.
498 * current image. Can be called from any thread.
500 void NotifyPaintedImage(Image* aPainted) {
501 ReentrantMonitorAutoEnter mon(mReentrantMonitor);
503 nsRefPtr<Image> current = mActiveImage;
504 if (aPainted == current) {
505 if (mPaintTime.IsNull()) {
506 mPaintTime = TimeStamp::Now();
507 mPaintCount++;
509 } else if (!mPreviousImagePainted) {
510 // While we were painting this image, the current image changed. We
511 // still must count it as painted, but can't set mPaintTime, since we're
512 // no longer the current image.
513 mPaintCount++;
514 mPreviousImagePainted = true;
517 if (mCompositionNotifySink) {
518 mCompositionNotifySink->DidComposite();
522 void SetCompositionNotifySink(CompositionNotifySink *aSink) {
523 mCompositionNotifySink = aSink;
526 private:
527 typedef mozilla::ReentrantMonitor ReentrantMonitor;
529 // Private destructor, to discourage deletion outside of Release():
530 B2G_ACL_EXPORT ~ImageContainer();
532 void SetCurrentImageInternal(Image* aImage);
534 // This is called to ensure we have an active image, this may not be true
535 // when we're storing image information in a RemoteImageData structure.
536 // NOTE: If we have remote data mRemoteDataMutex should be locked when
537 // calling this function!
538 void EnsureActiveImage();
540 // ReentrantMonitor to protect thread safe access to the "current
541 // image", and any other state which is shared between threads.
542 ReentrantMonitor mReentrantMonitor;
544 // Performs necessary housekeeping to ensure the painted frame statistics
545 // are accurate. Must be called by SetCurrentImage() implementations with
546 // mReentrantMonitor held.
547 void CurrentImageChanged() {
548 mReentrantMonitor.AssertCurrentThreadIn();
549 mPreviousImagePainted = !mPaintTime.IsNull();
550 mPaintTime = TimeStamp();
553 nsRefPtr<Image> mActiveImage;
555 // Number of contained images that have been painted at least once. It's up
556 // to the ImageContainer implementation to ensure accesses to this are
557 // threadsafe.
558 uint32_t mPaintCount;
560 // Time stamp at which the current image was first painted. It's up to the
561 // ImageContainer implementation to ensure accesses to this are threadsafe.
562 TimeStamp mPaintTime;
564 // Denotes whether the previous image was painted.
565 bool mPreviousImagePainted;
567 // This is the image factory used by this container, layer managers using
568 // this container can set an alternative image factory that will be used to
569 // create images for this container.
570 nsRefPtr<ImageFactory> mImageFactory;
572 gfx::IntSize mScaleHint;
574 nsRefPtr<BufferRecycleBin> mRecycleBin;
576 CompositionNotifySink *mCompositionNotifySink;
578 // This member points to an ImageClient if this ImageContainer was
579 // sucessfully created with ENABLE_ASYNC, or points to null otherwise.
580 // 'unsuccessful' in this case only means that the ImageClient could not
581 // be created, most likely because off-main-thread compositing is not enabled.
582 // In this case the ImageContainer is perfectly usable, but it will forward
583 // frames to the compositor through transactions in the main thread rather than
584 // asynchronusly using the ImageBridge IPDL protocol.
585 ImageClient* mImageClient;
588 class AutoLockImage
590 public:
591 explicit AutoLockImage(ImageContainer *aContainer) : mContainer(aContainer) { mImage = mContainer->LockCurrentImage(); }
592 AutoLockImage(ImageContainer *aContainer, RefPtr<gfx::SourceSurface> *aSurface) : mContainer(aContainer) {
593 *aSurface = mContainer->LockCurrentAsSourceSurface(&mSize, getter_AddRefs(mImage));
595 ~AutoLockImage() { if (mContainer) { mContainer->UnlockCurrentImage(); } }
597 Image* GetImage() { return mImage; }
598 const gfx::IntSize &GetSize() { return mSize; }
600 void Unlock() {
601 if (mContainer) {
602 mImage = nullptr;
603 mContainer->UnlockCurrentImage();
604 mContainer = nullptr;
608 /** Things get a little tricky here, because our underlying image can -still-
609 * change, and OS X requires a complicated callback mechanism to update this
610 * we need to support staying the lock and getting the new image in a proper
611 * way. This method makes any images retrieved with GetImage invalid!
613 void Refresh() {
614 if (mContainer) {
615 mContainer->UnlockCurrentImage();
616 mImage = mContainer->LockCurrentImage();
620 private:
621 ImageContainer *mContainer;
622 nsRefPtr<Image> mImage;
623 gfx::IntSize mSize;
626 struct PlanarYCbCrData {
627 // Luminance buffer
628 uint8_t* mYChannel;
629 int32_t mYStride;
630 gfx::IntSize mYSize;
631 int32_t mYSkip;
632 // Chroma buffers
633 uint8_t* mCbChannel;
634 uint8_t* mCrChannel;
635 int32_t mCbCrStride;
636 gfx::IntSize mCbCrSize;
637 int32_t mCbSkip;
638 int32_t mCrSkip;
639 // Picture region
640 uint32_t mPicX;
641 uint32_t mPicY;
642 gfx::IntSize mPicSize;
643 StereoMode mStereoMode;
645 nsIntRect GetPictureRect() const {
646 return nsIntRect(mPicX, mPicY,
647 mPicSize.width,
648 mPicSize.height);
651 PlanarYCbCrData()
652 : mYChannel(nullptr), mYStride(0), mYSize(0, 0), mYSkip(0)
653 , mCbChannel(nullptr), mCrChannel(nullptr)
654 , mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
655 , mPicX(0), mPicY(0), mPicSize(0, 0), mStereoMode(StereoMode::MONO)
659 /****** Image subtypes for the different formats ******/
662 * We assume that the image data is in the REC 470M color space (see
663 * Theora specification, section 4.3.1).
665 * The YCbCr format can be:
667 * 4:4:4 - CbCr width/height are the same as Y.
668 * 4:2:2 - CbCr width is half that of Y. Height is the same.
669 * 4:2:0 - CbCr width and height is half that of Y.
671 * The color format is detected based on the height/width ratios
672 * defined above.
674 * The Image that is rendered is the picture region defined by
675 * mPicX, mPicY and mPicSize. The size of the rendered image is
676 * mPicSize, not mYSize or mCbCrSize.
678 * mYSkip, mCbSkip, mCrSkip are added to support various output
679 * formats from hardware decoder. They are per-pixel skips in the
680 * source image.
682 * For example when image width is 640, mYStride is 670, mYSkip is 3,
683 * the mYChannel buffer looks like:
685 * |<----------------------- mYStride ----------------------------->|
686 * |<----------------- mYSize.width --------------->|
687 * 0 3 6 9 12 15 18 21 659 669
688 * |----------------------------------------------------------------|
689 * |Y___Y___Y___Y___Y___Y___Y___Y... |%%%%%%%%%|
690 * |Y___Y___Y___Y___Y___Y___Y___Y... |%%%%%%%%%|
691 * |Y___Y___Y___Y___Y___Y___Y___Y... |%%%%%%%%%|
692 * | |<->|
693 * mYSkip
695 class PlanarYCbCrImage : public Image {
696 public:
697 typedef PlanarYCbCrData Data;
699 enum {
700 MAX_DIMENSION = 16384
703 virtual ~PlanarYCbCrImage();
706 * This makes a copy of the data buffers, in order to support functioning
707 * in all different layer managers.
709 virtual void SetData(const Data& aData);
712 * This doesn't make a copy of the data buffers. Can be used when mBuffer is
713 * pre allocated with AllocateAndGetNewBuffer(size) and then SetDataNoCopy is
714 * called to only update the picture size, planes etc. fields in mData.
715 * The GStreamer media backend uses this to decode into PlanarYCbCrImage(s)
716 * directly.
718 virtual void SetDataNoCopy(const Data &aData);
721 * This allocates and returns a new buffer
723 virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize);
726 * Ask this Image to not convert YUV to RGB during SetData, and make
727 * the original data available through GetData. This is optional,
728 * and not all PlanarYCbCrImages will support it.
730 virtual void SetDelayedConversion(bool aDelayed) { }
733 * Grab the original YUV data. This is optional.
735 virtual const Data* GetData() { return &mData; }
738 * Return the number of bytes of heap memory used to store this image.
740 virtual uint32_t GetDataSize() { return mBufferSize; }
742 virtual bool IsValid() { return !!mBufferSize; }
744 virtual gfx::IntSize GetSize() { return mSize; }
746 explicit PlanarYCbCrImage(BufferRecycleBin *aRecycleBin);
748 virtual SharedPlanarYCbCrImage *AsSharedPlanarYCbCrImage() { return nullptr; }
750 virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
751 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
754 virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
756 protected:
758 * Make a copy of the YCbCr data into local storage.
760 * @param aData Input image data.
762 void CopyData(const Data& aData);
765 * Return a buffer to store image data in.
766 * The default implementation returns memory that can
767 * be freed wit delete[]
769 virtual uint8_t* AllocateBuffer(uint32_t aSize);
771 TemporaryRef<gfx::SourceSurface> GetAsSourceSurface();
773 void SetOffscreenFormat(gfxImageFormat aFormat) { mOffscreenFormat = aFormat; }
774 gfxImageFormat GetOffscreenFormat();
776 nsAutoArrayPtr<uint8_t> mBuffer;
777 uint32_t mBufferSize;
778 Data mData;
779 gfx::IntSize mSize;
780 gfxImageFormat mOffscreenFormat;
781 nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
782 nsRefPtr<BufferRecycleBin> mRecycleBin;
786 * Currently, the data in a CairoImage surface is treated as being in the
787 * device output color space. This class is very simple as all backends
788 * have to know about how to deal with drawing a cairo image.
790 class CairoImage MOZ_FINAL : public Image {
791 public:
792 struct Data {
793 gfx::IntSize mSize;
794 RefPtr<gfx::SourceSurface> mSourceSurface;
798 * This can only be called on the main thread. It may add a reference
799 * to the surface (which will eventually be released on the main thread).
800 * The surface must not be modified after this call!!!
802 void SetData(const Data& aData)
804 mSize = aData.mSize;
805 mSourceSurface = aData.mSourceSurface;
808 virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE
810 return mSourceSurface.get();
813 virtual TextureClient* GetTextureClient(CompositableClient* aClient) MOZ_OVERRIDE;
815 virtual gfx::IntSize GetSize() MOZ_OVERRIDE { return mSize; }
817 CairoImage();
818 ~CairoImage();
820 gfx::IntSize mSize;
822 nsCountedRef<nsMainThreadSourceSurfaceRef> mSourceSurface;
823 nsDataHashtable<nsUint32HashKey, RefPtr<TextureClient> > mTextureClients;
826 #ifdef MOZ_WIDGET_GONK
827 class OverlayImage : public Image {
829 * OverlayImage is a special Image type that does not hold any buffer.
830 * It only hold an Id as identifier to the real content of the Image.
831 * Therefore, OverlayImage must be handled by some specialized hardware(e.g. HWC)
832 * to show its content.
834 public:
835 struct Data {
836 int32_t mOverlayId;
837 gfx::IntSize mSize;
840 OverlayImage() : Image(nullptr, ImageFormat::OVERLAY_IMAGE) { mOverlayId = INVALID_OVERLAY; }
842 void SetData(const Data& aData)
844 mOverlayId = aData.mOverlayId;
845 mSize = aData.mSize;
848 TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; } ;
849 int32_t GetOverlayId() { return mOverlayId; }
851 gfx::IntSize GetSize() { return mSize; }
853 private:
854 int32_t mOverlayId;
855 gfx::IntSize mSize;
857 #endif
859 } //namespace
860 } //namespace
862 #endif