image/VectorImage.h
author Phil Ringnalda <philringnalda@gmail.com>
Wed, 28 Oct 2015 22:57:43 -0700
changeset 270180 b4c323832f317d650acd4bd7066d9432f3c1768c
parent 268184 e8c7dfe727cd970e2c3294934e2927b14143c205
child 306983 37340346a89e3ff5680559afabbc430ffaf9bb74
permissions -rw-r--r--
Back out 8 changesets (bug 1207355) for OS X 10.10 reftest failures in generated-content/ CLOSED TREE Backed out changeset aafd6db2fbb4 (bug 1207355) Backed out changeset 9dd950b837fb (bug 1207355) Backed out changeset e941e0e106a1 (bug 1207355) Backed out changeset ecebca101fcb (bug 1207355) Backed out changeset 08f2017137e1 (bug 1207355) Backed out changeset 3dc69e37c9b4 (bug 1207355) Backed out changeset bcdf51edb121 (bug 1207355) Backed out changeset 1d4c00dbf49a (bug 1207355)

/* -*- 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/. */

#ifndef mozilla_image_VectorImage_h
#define mozilla_image_VectorImage_h

#include "Image.h"
#include "nsIStreamListener.h"
#include "mozilla/MemoryReporting.h"

class nsIRequest;
class gfxDrawable;

namespace mozilla {
namespace image {

struct SVGDrawingParameters;
class  SVGDocumentWrapper;
class  SVGRootRenderingObserver;
class  SVGLoadEventListener;
class  SVGParseCompleteListener;

class VectorImage final : public ImageResource,
                          public nsIStreamListener
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIREQUESTOBSERVER
  NS_DECL_NSISTREAMLISTENER
  NS_DECL_IMGICONTAINER

  // (no public constructor - use ImageFactory)

  // Methods inherited from Image
  virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf)
    const override;
  virtual void CollectSizeOfSurfaces(nsTArray<SurfaceMemoryCounter>& aCounters,
                                     MallocSizeOf aMallocSizeOf) const override;

  virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
                                        nsISupports* aContext,
                                        nsIInputStream* aInStr,
                                        uint64_t aSourceOffset,
                                        uint32_t aCount) override;
  virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
                                       nsISupports* aContext,
                                       nsresult aResult,
                                       bool aLastPart) override;

  void OnSurfaceDiscarded() override;

  /**
   * Callback for SVGRootRenderingObserver.
   *
   * This just sets a dirty flag that we check in VectorImage::RequestRefresh,
   * which is called under the ticks of the refresh driver of any observing
   * documents that we may have. Only then (after all animations in this image
   * have been updated) do we send out "frame changed" notifications,
   */
  void InvalidateObserversOnNextRefreshDriverTick();

  // Callback for SVGParseCompleteListener.
  void OnSVGDocumentParsed();

  // Callbacks for SVGLoadEventListener.
  void OnSVGDocumentLoaded();
  void OnSVGDocumentError();

  virtual void ReportUseCounters() override;

protected:
  explicit VectorImage(ImageURL* aURI = nullptr);
  virtual ~VectorImage();

  virtual nsresult StartAnimation() override;
  virtual nsresult StopAnimation() override;
  virtual bool     ShouldAnimate() override;

  void CreateSurfaceAndShow(const SVGDrawingParameters& aParams);
  void Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams);

private:
  nsresult Init(const char* aMimeType, uint32_t aFlags);

  /**
   * In catastrophic circumstances like a GPU driver crash, we may lose our
   * surfaces even if they're locked. RecoverFromLossOfSurfaces discards all
   * existing surfaces, allowing us to recover.
   */
  void RecoverFromLossOfSurfaces();

  void CancelAllListeners();
  void SendInvalidationNotifications();

  RefPtr<SVGDocumentWrapper>       mSVGDocumentWrapper;
  RefPtr<SVGRootRenderingObserver> mRenderingObserver;
  RefPtr<SVGLoadEventListener>     mLoadEventListener;
  RefPtr<SVGParseCompleteListener> mParseCompleteListener;

  /// Count of locks on this image (roughly correlated to visible instances).
  uint32_t mLockCount;

  // Stored result from the Necko load of the image, which we save in
  // OnImageDataComplete if the underlying SVG document isn't loaded. If we save
  // this, we actually notify this progress (and clear this value) in
  // OnSVGDocumentLoaded or OnSVGDocumentError.
  Maybe<Progress> mLoadProgress;

  bool           mIsInitialized;          // Have we been initialized?
  bool           mDiscardable;            // Are we discardable?
  bool           mIsFullyLoaded;          // Has the SVG document finished
                                          // loading?
  bool           mIsDrawing;              // Are we currently drawing?
  bool           mHaveAnimations;         // Is our SVG content SMIL-animated?
                                          // (Only set after mIsFullyLoaded.)
  bool           mHasPendingInvalidation; // Invalidate observers next refresh
                                          // driver tick.

  friend class ImageFactory;
};

inline NS_IMETHODIMP VectorImage::GetAnimationMode(uint16_t* aAnimationMode) {
  return GetAnimationModeInternal(aAnimationMode);
}

inline NS_IMETHODIMP VectorImage::SetAnimationMode(uint16_t aAnimationMode) {
  return SetAnimationModeInternal(aAnimationMode);
}

} // namespace image
} // namespace mozilla

#endif // mozilla_image_VectorImage_h