|
|
|
|
| 34 |
* the terms of any one of the MPL, the GPL or the LGPL. |
34 |
* the terms of any one of the MPL, the GPL or the LGPL. |
| 35 |
* |
35 |
* |
| 36 |
* ***** END LICENSE BLOCK ***** */ |
36 |
* ***** END LICENSE BLOCK ***** */ |
| 37 |
|
37 |
|
| 38 |
#ifndef GFX_IMAGELAYER_H |
38 |
#ifndef GFX_IMAGELAYER_H |
| 39 |
#define GFX_IMAGELAYER_H |
39 |
#define GFX_IMAGELAYER_H |
| 40 |
|
40 |
|
| 41 |
#include "Layers.h" |
41 |
#include "Layers.h" |
|
|
42 |
#include "mozilla/TimeStamp.h" |
| 42 |
|
43 |
|
| 43 |
#include "gfxPattern.h" |
44 |
#include "gfxPattern.h" |
| 44 |
#include "nsThreadUtils.h" |
45 |
#include "nsThreadUtils.h" |
| 45 |
#include "nsCoreAnimationSupport.h" |
46 |
#include "nsCoreAnimationSupport.h" |
| 46 |
|
47 |
|
| 47 |
namespace mozilla { |
48 |
namespace mozilla { |
| 48 |
namespace layers { |
49 |
namespace layers { |
| 49 |
|
50 |
|
|
|
| 126 |
* (because layers can only be used on the main thread) and we want to |
127 |
* (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 |
* be able to set the current Image from any thread, to facilitate |
| 128 |
* video playback without involving the main thread, for example. |
129 |
* video playback without involving the main thread, for example. |
| 129 |
*/ |
130 |
*/ |
| 130 |
class THEBES_API ImageContainer { |
131 |
class THEBES_API ImageContainer { |
| 131 |
THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer) |
132 |
THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer) |
| 132 |
|
133 |
|
| 133 |
public: |
134 |
public: |
| 134 |
ImageContainer() {} |
135 |
ImageContainer() : mPaintCount(0), mPreviousImagePainted(PR_FALSE) {} |
| 135 |
virtual ~ImageContainer() {} |
136 |
virtual ~ImageContainer() {} |
| 136 |
|
137 |
|
| 137 |
/** |
138 |
/** |
| 138 |
* Create an Image in one of the given formats. |
139 |
* Create an Image in one of the given formats. |
| 139 |
* Picks the "best" format from the list and creates an Image of that |
140 |
* Picks the "best" format from the list and creates an Image of that |
| 140 |
* format. |
141 |
* format. |
| 141 |
* Returns null if this backend does not support any of the formats. |
142 |
* Returns null if this backend does not support any of the formats. |
| 142 |
*/ |
143 |
*/ |
| 143 |
virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats, |
144 |
virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats, |
| 144 |
PRUint32 aNumFormats) = 0; |
145 |
PRUint32 aNumFormats) = 0; |
| 145 |
|
146 |
|
| 146 |
/** |
147 |
/** |
| 147 |
* Set an Image as the current image to display. The Image must have |
148 |
* Set an Image as the current image to display. The Image must have |
| 148 |
* been created by this ImageContainer. |
149 |
* been created by this ImageContainer. |
|
|
150 |
* |
| 151 |
* Implementations must call CurrentImageChanged() in a threadsafe manner. |
| 149 |
* |
152 |
* |
| 150 |
* The Image data must not be modified after this method is called! |
153 |
* The Image data must not be modified after this method is called! |
| 151 |
*/ |
154 |
*/ |
| 152 |
virtual void SetCurrentImage(Image* aImage) = 0; |
155 |
virtual void SetCurrentImage(Image* aImage) = 0; |
| 153 |
|
156 |
|
| 154 |
/** |
157 |
/** |
| 155 |
* Get the current Image. |
158 |
* Get the current Image. |
| 156 |
* This has to add a reference since otherwise there are race conditions |
159 |
* This has to add a reference since otherwise there are race conditions |
|
|
| 206 |
|
209 |
|
| 207 |
/** |
210 |
/** |
| 208 |
* Get the layer manager type this image container was created with, |
211 |
* 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 |
* presumably its users might want to do something special if types do not |
| 210 |
* match. |
213 |
* match. |
| 211 |
*/ |
214 |
*/ |
| 212 |
virtual LayerManager::LayersBackend GetBackendType() = 0; |
215 |
virtual LayerManager::LayersBackend GetBackendType() = 0; |
| 213 |
|
216 |
|
|
|
217 |
/** |
| 218 |
* Returns the time at which the currently contained image was first |
| 219 |
* painted. This is reset every time a new image is set as the current |
| 220 |
* image. Note this may return a null timestamp if the current image |
| 221 |
* has not yet been painted. Threadsafe. |
| 222 |
*/ |
| 223 |
virtual TimeStamp GetPaintTime() = 0; |
| 224 |
|
| 225 |
/** |
| 226 |
* Returns the number of images which have been contained in this container |
| 227 |
* and painted at least once. Threadsafe. |
| 228 |
*/ |
| 229 |
virtual PRUint32 GetPaintCount() = 0; |
| 230 |
|
| 231 |
/** |
| 232 |
* Notifies the container that aImage has been painted. Note we must pass |
| 233 |
* in a pointer to the image that has been painted, as the current image |
| 234 |
* can change while we're rendering, and in that case we don't want to |
| 235 |
* record the paint time of the just painted image as the paint time of the |
| 236 |
* current image. Threadsafe. |
| 237 |
*/ |
| 238 |
virtual void NotifyPaintedImage(Image* aImage) = 0; |
| 239 |
|
| 214 |
protected: |
240 |
protected: |
| 215 |
LayerManager* mManager; |
241 |
LayerManager* mManager; |
| 216 |
|
242 |
|
| 217 |
ImageContainer(LayerManager* aManager) : mManager(aManager) {} |
243 |
ImageContainer(LayerManager* aManager) |
|
|
244 |
: mManager(aManager), |
| 245 |
mPaintCount(0), |
| 246 |
mPreviousImagePainted(PR_FALSE) |
| 247 |
{} |
| 248 |
|
| 249 |
// Increments mPaintCount if this is the first time aPainted has been |
| 250 |
// painted, and sets mPaintTime if the painted image is the current image |
| 251 |
// (aCurrent). It's up to the ImageContainer implementation to ensure this |
| 252 |
// is called in a threadsafe manner. |
| 253 |
void RecordPaintStats(Image* aPainted, Image* aCurrent) |
| 254 |
{ |
| 255 |
if (aPainted == aCurrent) { |
| 256 |
if (mPaintTime.IsNull()) { |
| 257 |
mPaintTime = TimeStamp::Now(); |
| 258 |
mPaintCount++; |
| 259 |
} |
| 260 |
} else if (!mPreviousImagePainted) { |
| 261 |
// While we were painting this image, the current image changed. We |
| 262 |
// still must count it as painted, but can't set mPaintTime, since we're |
| 263 |
// no longer the current image. |
| 264 |
mPaintCount++; |
| 265 |
mPreviousImagePainted = PR_TRUE; |
| 266 |
} |
| 267 |
} |
| 268 |
|
| 269 |
// Performs necessary housekeeping to ensure the painted frame statistics |
| 270 |
// are accurate. Must be called by SetCurrentImage() implementations in a |
| 271 |
// thread safe manner. |
| 272 |
void CurrentImageChanged() { |
| 273 |
mPreviousImagePainted = !mPaintTime.IsNull(); |
| 274 |
mPaintTime = TimeStamp(); |
| 275 |
} |
| 276 |
|
| 277 |
// Number of contained images that have been painted at least once. It's up |
| 278 |
// to the ImageContainer implementation to ensure accesses to this are |
| 279 |
// threadsafe. |
| 280 |
PRUint32 mPaintCount; |
| 281 |
|
| 282 |
// Time stamp at which the current image was first painted. It's up to the |
| 283 |
// ImageContainer implementation to ensure accesses to this are threadsafe. |
| 284 |
TimeStamp mPaintTime; |
| 285 |
|
| 286 |
// Denotes whether the previous image was painted. |
| 287 |
PRBool mPreviousImagePainted; |
| 218 |
}; |
288 |
}; |
| 219 |
|
289 |
|
| 220 |
/** |
290 |
/** |
| 221 |
* A Layer which renders an Image. |
291 |
* A Layer which renders an Image. |
| 222 |
*/ |
292 |
*/ |
| 223 |
class THEBES_API ImageLayer : public Layer { |
293 |
class THEBES_API ImageLayer : public Layer { |
| 224 |
public: |
294 |
public: |
| 225 |
/** |
295 |
/** |