/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * An interface for objects which can either store a surface or dynamically * generate one, and various implementations.
*/
/** * An interface for objects which can either store a surface or dynamically * generate one.
*/ class ISurfaceProvider : public WebRenderImageProvider { public: // Subclasses may or may not be XPCOM classes, so we just require that they // implement AddRef and Release.
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
/// @return key data used for identifying which image this ISurfaceProvider is /// associated with in the surface cache.
ImageKey GetImageKey() const { return mImageKey; }
/// @return key data used to uniquely identify this ISurfaceProvider's cache /// entry in the surface cache. const SurfaceKey& GetSurfaceKey() const { return mSurfaceKey; }
/// @return a drawable reference to a surface.
DrawableSurface Surface();
/// @return true if DrawableRef() will return a completely decoded surface. virtualbool IsFinished() const = 0;
/// @return true if the underlying decoder is currently fully decoded. For /// animated images, this means that at least every frame has been decoded /// at least once. It does not guarantee that all of the frames are present, /// as the surface provider has the option to discard as it deems necessary. virtualbool IsFullyDecoded() const { return IsFinished(); }
/// @return the number of bytes of memory this ISurfaceProvider is expected to /// require. Optimizations may result in lower real memory usage. Trivial /// overhead is ignored. Because this value is used in bookkeeping, it's /// important that it be constant over the lifetime of this object. virtual size_t LogicalSizeInBytes() const = 0;
/// @return the actual number of bytes of memory this ISurfaceProvider is /// using. May vary over the lifetime of the ISurfaceProvider. The default /// implementation is appropriate for static ISurfaceProviders. virtualvoid AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf, const AddSizeOfCb& aCallback) {
DrawableFrameRef ref = DrawableRef(/* aFrame = */ 0); if (!ref) { return;
}
/// @return the availability state of this ISurfaceProvider, which indicates /// whether DrawableRef() could successfully return a surface. Should only be /// called from SurfaceCache code as it relies on SurfaceCache for /// synchronization.
AvailabilityState& Availability() { return mAvailability; } const AvailabilityState& Availability() const { return mAvailability; }
/// @return an eagerly computed drawable reference to a surface. For /// dynamically generated animation surfaces, @aFrame specifies the 0-based /// index of the desired frame. virtual DrawableFrameRef DrawableRef(size_t aFrame) = 0;
/// @return an imgFrame at the 0-based index of the desired frame, as /// specified by @aFrame. Only applies for animated images. virtual already_AddRefed<imgFrame> GetFrame(size_t aFrame) {
MOZ_ASSERT_UNREACHABLE("Surface provider does not support direct access!"); return nullptr;
}
/// @return true if this ISurfaceProvider is locked. (@see SetLocked()) /// Should only be called from SurfaceCache code as it relies on SurfaceCache /// for synchronization. virtualbool IsLocked() const = 0;
/// If @aLocked is true, hint that this ISurfaceProvider is in use and it /// should avoid releasing its resources. Should only be called from /// SurfaceCache code as it relies on SurfaceCache for synchronization. virtualvoid SetLocked(bool aLocked) = 0;
/** * A reference to a surface (stored in an imgFrame) that holds the surface in * memory, guaranteeing that it can be drawn. If you have a DrawableSurface * |surf| and |if (surf)| returns true, then calls to |surf->Draw()| and * |surf->GetSourceSurface()| are guaranteed to succeed. * * Note that the surface may be computed lazily, so a DrawableSurface should not * be dereferenced (i.e., operator->() should not be called) until you're * sure that you want to draw it.
*/ class MOZ_STACK_CLASS DrawableSurface final { public:
DrawableSurface() : mHaveSurface(false) {}
/** * If this DrawableSurface is dynamically generated from an animation, attempt * to seek to frame @aFrame, where @aFrame is a 0-based index into the frames * of the animation. Otherwise, nothing will blow up at runtime, but we assert * in debug builds, since calling this in an unexpected situation probably * indicates a bug. * * @return a successful result if we could obtain frame @aFrame. Note that * |mHaveSurface| being true means that we're guaranteed to have *some* frame, * so the caller can dereference this DrawableSurface even if Seek() fails, * but while nothing will blow up, the frame won't be the one they expect.
*/
nsresult Seek(size_t aFrame) {
MOZ_ASSERT(mHaveSurface, "Trying to seek an empty DrawableSurface?");
if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to seek a static DrawableSurface?"); return NS_ERROR_FAILURE;
}
mDrawableRef = mProvider->DrawableRef(aFrame);
return mDrawableRef ? NS_OK : NS_ERROR_FAILURE;
}
already_AddRefed<imgFrame> GetFrame(size_t aFrame) {
MOZ_ASSERT(mHaveSurface, "Trying to get on an empty DrawableSurface?");
if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to get on a static DrawableSurface?"); return nullptr;
}
return mProvider->GetFrame(aFrame);
}
void Reset() { if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to reset a static DrawableSurface?"); return;
}
mProvider->Reset();
}
void Advance(size_t aFrame) { if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?"); return;
}
mProvider->Advance(aFrame);
}
bool MayAdvance() const { if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?"); returnfalse;
}
return mProvider->MayAdvance();
}
void MarkMayAdvance() { if (!mProvider) {
MOZ_ASSERT_UNREACHABLE("Trying to advance a static DrawableSurface?"); return;
}
mProvider->MarkMayAdvance();
}
bool IsFullyDecoded() const { if (!mProvider) {
MOZ_ASSERT_UNREACHABLE( "Trying to check decoding state of a static DrawableSurface?"); returnfalse;
}
// If we weren't created with a DrawableFrameRef directly, we should've been // created with an ISurfaceProvider which can give us one. Note that if // Seek() has been called, we'll already have a DrawableFrameRef, so we // won't need to get one here. if (!mDrawableRef) {
MOZ_ASSERT(mProvider);
mDrawableRef = mProvider->DrawableRef(/* aFrame = */ 0);
}
// Surface() is implemented here so that DrawableSurface's definition is // visible. inline DrawableSurface ISurfaceProvider::Surface() { return DrawableSurface(WrapNotNull(this));
}
/** * An ISurfaceProvider that stores a single surface.
*/ class SimpleSurfaceProvider final : public ISurfaceProvider { public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SimpleSurfaceProvider, override)
// If we're locked, hold a DrawableFrameRef to |mSurface|, which will keep // any volatile buffer it owns in memory.
mLockRef = aLocked ? mSurface->DrawableRef() : DrawableFrameRef();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.