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
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/
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
15 * The Original Code is Mozilla Corporation code.
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.
22 * Robert O'Callahan <robert@ocallahan.org>
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.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef GFX_IMAGELAYER_H
39 #define GFX_IMAGELAYER_H
43 #include "gfxPattern.h"
44 #include "nsThreadUtils.h"
45 #include "nsCoreAnimationSupport.h"
52 STEREO_MODE_LEFT_RIGHT
,
53 STEREO_MODE_RIGHT_LEFT
,
54 STEREO_MODE_BOTTOM_TOP
,
55 STEREO_MODE_TOP_BOTTOM
59 * A class representing a buffer of pixel data. The data can be in one
60 * of various formats including YCbCr.
62 * Create an image using an ImageContainer. Fill the image with data, and
63 * then call ImageContainer::SetImage to display it. An image must not be
64 * modified after calling SetImage. Image implementations do not need to
65 * perform locking; when filling an Image, the Image client is responsible
66 * for ensuring only one thread accesses the Image at a time, and after
67 * SetImage the image is immutable.
69 * When resampling an Image, only pixels within the buffer should be
70 * sampled. For example, cairo images should be sampled in EXTEND_PAD mode.
72 class THEBES_API Image
{
73 THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(Image
)
80 * The PLANAR_YCBCR format creates a PlanarYCbCrImage. All backends should
81 * support this format, because the Ogg video decoder depends on it.
82 * The maximum image width and height is 16384.
87 * The CAIRO_SURFACE format creates a CairoImage. All backends should
88 * support this format, because video rendering sometimes requires it.
90 * This format is useful even though a ThebesLayer could be used.
91 * It makes it easy to render a cairo surface when another Image format
92 * could be used. It can also avoid copying the surface data in some
95 * Images in CAIRO_SURFACE format should only be created and
96 * manipulated on the main thread, since the underlying cairo surface
97 * is main-thread-only.
102 * The MAC_IO_SURFACE format creates a MacIOSurfaceImage. This
103 * is only supported on Mac with OpenGL layers.
105 * It wraps an IOSurface object and binds it directly to a GL texture.
110 Format
GetFormat() { return mFormat
; }
111 void* GetImplData() { return mImplData
; }
114 Image(void* aImplData
, Format aFormat
) :
115 mImplData(aImplData
),
124 * A class that manages Images for an ImageLayer. The only reason
125 * we need a separate class here is that ImageLayers aren't threadsafe
126 * (because layers can only be used on the main thread) and we want to
127 * be able to set the current Image from any thread, to facilitate
128 * video playback without involving the main thread, for example.
130 class THEBES_API ImageContainer
{
131 THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer
)
135 virtual ~ImageContainer() {}
138 * Create an Image in one of the given formats.
139 * Picks the "best" format from the list and creates an Image of that
141 * Returns null if this backend does not support any of the formats.
143 virtual already_AddRefed
<Image
> CreateImage(const Image::Format
* aFormats
,
144 PRUint32 aNumFormats
) = 0;
147 * Set an Image as the current image to display. The Image must have
148 * been created by this ImageContainer.
150 * The Image data must not be modified after this method is called!
152 virtual void SetCurrentImage(Image
* aImage
) = 0;
155 * Get the current Image.
156 * This has to add a reference since otherwise there are race conditions
157 * where the current image is destroyed before the caller can add
160 virtual already_AddRefed
<Image
> GetCurrentImage() = 0;
163 * Get the current image as a gfxASurface. This is useful for fallback
165 * This can only be called from the main thread, since cairo objects
166 * can only be used from the main thread.
167 * This is defined here and not on Image because it's possible (likely)
168 * that some backends will make an Image "ready to draw" only when it
169 * becomes the current image for an image container.
170 * Returns null if there is no current image.
171 * Returns the size in aSize.
172 * The returned surface will never be modified. The caller must not
175 virtual already_AddRefed
<gfxASurface
> GetCurrentAsSurface(gfxIntSize
* aSizeResult
) = 0;
178 * Returns the layer manager for this container. This can only
179 * be used on the main thread, since layer managers should only be
180 * accessed on the main thread.
182 LayerManager
* Manager()
184 NS_PRECONDITION(NS_IsMainThread(), "Must be called on main thread");
189 * Returns the size of the image in pixels.
191 virtual gfxIntSize
GetCurrentSize() = 0;
194 * Set a new layer manager for this image container. It must be
195 * either of the same type as the container's current layer manager,
196 * or null. TRUE is returned on success.
198 virtual PRBool
SetLayerManager(LayerManager
*aManager
) = 0;
201 * Sets a size that the image is expected to be rendered at.
202 * This is a hint for image backends to optimize scaling.
203 * Default implementation in this class is to ignore the hint.
205 virtual void SetScaleHint(const gfxIntSize
& /* aScaleHint */) { }
208 * Get the layer manager type this image container was created with,
209 * presumably its users might want to do something special if types do not
212 virtual LayerManager::LayersBackend
GetBackendType() = 0;
215 LayerManager
* mManager
;
217 ImageContainer(LayerManager
* aManager
) : mManager(aManager
) {}
221 * A Layer which renders an Image.
223 class THEBES_API ImageLayer
: public Layer
{
226 * CONSTRUCTION PHASE ONLY
227 * Set the ImageContainer. aContainer must have the same layer manager
230 void SetContainer(ImageContainer
* aContainer
)
232 NS_ASSERTION(!aContainer
->Manager() || aContainer
->Manager() == Manager(),
233 "ImageContainer must have the same manager as the ImageLayer");
234 mContainer
= aContainer
;
237 * CONSTRUCTION PHASE ONLY
238 * Set the filter used to resample this image if necessary.
240 void SetFilter(gfxPattern::GraphicsFilter aFilter
) { mFilter
= aFilter
; }
242 ImageContainer
* GetContainer() { return mContainer
; }
243 gfxPattern::GraphicsFilter
GetFilter() { return mFilter
; }
245 MOZ_LAYER_DECL_NAME("ImageLayer", TYPE_IMAGE
)
247 virtual void ComputeEffectiveTransforms(const gfx3DMatrix
& aTransformToSurface
)
249 // Snap image edges to pixel boundaries
250 gfxRect
snap(0, 0, 0, 0);
252 gfxIntSize size
= mContainer
->GetCurrentSize();
253 snap
.size
= gfxSize(size
.width
, size
.height
);
255 // Snap our local transform first, and snap the inherited transform as well.
256 // This makes our snapping equivalent to what would happen if our content
257 // was drawn into a ThebesLayer (gfxContext would snap using the local
258 // transform, then we'd snap again when compositing the ThebesLayer).
259 mEffectiveTransform
=
260 SnapTransform(GetLocalTransform(), snap
, nsnull
)*
261 SnapTransform(aTransformToSurface
, gfxRect(0, 0, 0, 0), nsnull
);
265 ImageLayer(LayerManager
* aManager
, void* aImplData
)
266 : Layer(aManager
, aImplData
), mFilter(gfxPattern::FILTER_GOOD
) {}
268 virtual nsACString
& PrintInfo(nsACString
& aTo
, const char* aPrefix
);
270 nsRefPtr
<ImageContainer
> mContainer
;
271 gfxPattern::GraphicsFilter mFilter
;
274 /****** Image subtypes for the different formats ******/
277 * We assume that the image data is in the REC 470M color space (see
278 * Theora specification, section 4.3.1).
280 * The YCbCr format can be:
282 * 4:4:4 - CbCr width/height are the same as Y.
283 * 4:2:2 - CbCr width is half that of Y. Height is the same.
284 * 4:2:0 - CbCr width and height is half that of Y.
286 * The color format is detected based on the height/width ratios
289 * The Image that is rendered is the picture region defined by
290 * mPicX, mPicY and mPicSize. The size of the rendered image is
291 * mPicSize, not mYSize or mCbCrSize.
293 class THEBES_API PlanarYCbCrImage
: public Image
{
304 gfxIntSize mCbCrSize
;
309 StereoMode mStereoMode
;
313 MAX_DIMENSION
= 16384
317 * This makes a copy of the data buffers.
318 * XXX Eventually we will change this to not make a copy of the data,
319 * Right now it doesn't matter because the BasicLayer implementation
320 * does YCbCr conversion here anyway.
322 virtual void SetData(const Data
& aData
) = 0;
325 PlanarYCbCrImage(void* aImplData
) : Image(aImplData
, PLANAR_YCBCR
) {}
329 * Currently, the data in a CairoImage surface is treated as being in the
330 * device output color space.
332 class THEBES_API CairoImage
: public Image
{
335 gfxASurface
* mSurface
;
340 * This can only be called on the main thread. It may add a reference
341 * to the surface (which will eventually be released on the main thread).
342 * The surface must not be modified after this call!!!
344 virtual void SetData(const Data
& aData
) = 0;
347 CairoImage(void* aImplData
) : Image(aImplData
, CAIRO_SURFACE
) {}
351 class THEBES_API MacIOSurfaceImage
: public Image
{
354 nsIOSurface
* mIOSurface
;
358 * This can only be called on the main thread. It may add a reference
359 * to the surface (which will eventually be released on the main thread).
360 * The surface must not be modified after this call!!!
362 virtual void SetData(const Data
& aData
) = 0;
365 * Temporary hacks to force plugin drawing during an empty transaction.
366 * This should not be used for anything else, and will be removed
367 * when async plugin rendering is complete.
369 typedef void (*UpdateSurfaceCallback
)(ImageContainer
* aContainer
, void* aInstanceOwner
);
370 virtual void SetCallback(UpdateSurfaceCallback aCallback
, void* aInstanceOwner
) =0;
373 MacIOSurfaceImage(void* aImplData
) : Image(aImplData
, MAC_IO_SURFACE
) {}
380 #endif /* GFX_IMAGELAYER_H */