summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/codec/SkFrameHolder.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/codec/SkFrameHolder.h')
-rw-r--r--gfx/skia/skia/src/codec/SkFrameHolder.h206
1 files changed, 206 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/codec/SkFrameHolder.h b/gfx/skia/skia/src/codec/SkFrameHolder.h
new file mode 100644
index 0000000000..5facbd872a
--- /dev/null
+++ b/gfx/skia/skia/src/codec/SkFrameHolder.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFrameHolder_DEFINED
+#define SkFrameHolder_DEFINED
+
+#include "include/codec/SkCodec.h"
+#include "include/codec/SkCodecAnimation.h"
+#include "include/core/SkRect.h"
+#include "include/core/SkTypes.h"
+#include "include/private/SkEncodedInfo.h"
+#include "include/private/base/SkNoncopyable.h"
+
+/**
+ * Base class for a single frame of an animated image.
+ *
+ * Separate from SkCodec::FrameInfo, which is a pared down
+ * interface that only contains the info the client needs.
+ */
+class SkFrame : public SkNoncopyable {
+public:
+ SkFrame(int id)
+ : fId(id)
+ , fHasAlpha(false)
+ , fRequiredFrame(kUninitialized)
+ , fDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep)
+ , fDuration(0)
+ , fBlend(SkCodecAnimation::Blend::kSrcOver)
+ {
+ fRect.setEmpty();
+ }
+
+ virtual ~SkFrame() {}
+
+ /**
+ * An explicit move constructor, as
+ * https://en.cppreference.com/w/cpp/language/move_constructor says that
+ * there is no implicit move constructor if there are user-declared
+ * destructors, and we have one, immediately above.
+ *
+ * Without a move constructor, it is harder to use an SkFrame, or an
+ * SkFrame subclass, inside a std::vector.
+ */
+ SkFrame(SkFrame&&) = default;
+
+ /**
+ * 0-based index of the frame in the image sequence.
+ */
+ int frameId() const { return fId; }
+
+ /**
+ * How this frame reports its alpha.
+ *
+ * This only considers the rectangle of this frame, and
+ * considers it to have alpha even if it is opaque once
+ * blended with the frame behind it.
+ */
+ SkEncodedInfo::Alpha reportedAlpha() const {
+ return this->onReportedAlpha();
+ }
+
+ /**
+ * Cached value representing whether the frame has alpha,
+ * after compositing with the prior frame.
+ */
+ bool hasAlpha() const { return fHasAlpha; }
+
+ /**
+ * Cache whether the finished frame has alpha.
+ */
+ void setHasAlpha(bool alpha) { fHasAlpha = alpha; }
+
+ /**
+ * Whether enough of the frame has been read to determine
+ * fRequiredFrame and fHasAlpha.
+ */
+ bool reachedStartOfData() const { return fRequiredFrame != kUninitialized; }
+
+ /**
+ * The frame this one depends on.
+ *
+ * Must not be called until fRequiredFrame has been set properly.
+ */
+ int getRequiredFrame() const {
+ SkASSERT(this->reachedStartOfData());
+ return fRequiredFrame;
+ }
+
+ /**
+ * Set the frame that this frame depends on.
+ */
+ void setRequiredFrame(int req) { fRequiredFrame = req; }
+
+ /**
+ * Set the rectangle that is updated by this frame.
+ */
+ void setXYWH(int x, int y, int width, int height) {
+ fRect.setXYWH(x, y, width, height);
+ }
+
+ /**
+ * The rectangle that is updated by this frame.
+ */
+ SkIRect frameRect() const { return fRect; }
+
+ int xOffset() const { return fRect.x(); }
+ int yOffset() const { return fRect.y(); }
+ int width() const { return fRect.width(); }
+ int height() const { return fRect.height(); }
+
+ SkCodecAnimation::DisposalMethod getDisposalMethod() const {
+ return fDisposalMethod;
+ }
+
+ void setDisposalMethod(SkCodecAnimation::DisposalMethod disposalMethod) {
+ fDisposalMethod = disposalMethod;
+ }
+
+ /**
+ * Set the duration (in ms) to show this frame.
+ */
+ void setDuration(int duration) {
+ fDuration = duration;
+ }
+
+ /**
+ * Duration in ms to show this frame.
+ */
+ int getDuration() const {
+ return fDuration;
+ }
+
+ void setBlend(SkCodecAnimation::Blend blend) {
+ fBlend = blend;
+ }
+
+ SkCodecAnimation::Blend getBlend() const {
+ return fBlend;
+ }
+
+ /**
+ * Fill in the FrameInfo with details from this object.
+ */
+ void fillIn(SkCodec::FrameInfo*, bool fullyReceived) const;
+
+protected:
+ virtual SkEncodedInfo::Alpha onReportedAlpha() const = 0;
+
+private:
+ inline static constexpr int kUninitialized = -2;
+
+ const int fId;
+ bool fHasAlpha;
+ int fRequiredFrame;
+ SkIRect fRect;
+ SkCodecAnimation::DisposalMethod fDisposalMethod;
+ int fDuration;
+ SkCodecAnimation::Blend fBlend;
+};
+
+/**
+ * Base class for an object which holds the SkFrames of an
+ * image sequence.
+ */
+class SkFrameHolder : public SkNoncopyable {
+public:
+ SkFrameHolder()
+ : fScreenWidth(0)
+ , fScreenHeight(0)
+ {}
+
+ virtual ~SkFrameHolder() {}
+
+ /**
+ * Size of the image. Each frame will be contained in
+ * these dimensions (possibly after clipping).
+ */
+ int screenWidth() const { return fScreenWidth; }
+ int screenHeight() const { return fScreenHeight; }
+
+ /**
+ * Compute the opacity and required frame, based on
+ * the frame's reportedAlpha and how it blends
+ * with prior frames.
+ */
+ void setAlphaAndRequiredFrame(SkFrame*);
+
+ /**
+ * Return the frame with frameId i.
+ */
+ const SkFrame* getFrame(int i) const {
+ return this->onGetFrame(i);
+ }
+
+protected:
+ int fScreenWidth;
+ int fScreenHeight;
+
+ virtual const SkFrame* onGetFrame(int i) const = 0;
+};
+
+#endif // SkFrameHolder_DEFINED