blob: 29539ff908e2d04477acf0312eb5142ad6e0dfc4 [file] [log] [blame]
Leon Scroggins III557fbbe2017-05-23 09:37:21 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkFrameHolder_DEFINED
9#define SkFrameHolder_DEFINED
10
11#include "SkTypes.h"
12#include "SkCodecAnimation.h"
Leon Scroggins III33deb7e2017-06-07 12:31:51 -040013#include "SkCodecAnimationPriv.h"
Hal Canary466c7d62017-07-03 15:11:49 -040014#include "SkRect.h"
Leon Scroggins III557fbbe2017-05-23 09:37:21 -040015
16/**
17 * Base class for a single frame of an animated image.
18 *
19 * Separate from SkCodec::FrameInfo, which is a pared down
20 * interface that only contains the info the client needs.
21 */
22class SkFrame : public SkNoncopyable {
23public:
24 SkFrame(int id)
25 : fId(id)
26 , fHasAlpha(false)
27 , fRequiredFrame(kUninitialized)
Leon Scroggins III33deb7e2017-06-07 12:31:51 -040028 , fDisposalMethod(SkCodecAnimation::DisposalMethod::kKeep)
Leon Scroggins III557fbbe2017-05-23 09:37:21 -040029 , fDuration(0)
30 , fBlend(SkCodecAnimation::Blend::kPriorFrame)
31 {
32 fRect.setEmpty();
33 }
34
35 virtual ~SkFrame() {}
36
37 /**
38 * 0-based index of the frame in the image sequence.
39 */
40 int frameId() const { return fId; }
41
42 /**
43 * Whether this frame reports alpha.
44 *
45 * This only considers the rectangle of this frame, and
46 * considers it to have alpha even if it is opaque once
47 * blended with the frame behind it.
48 */
49 bool reportsAlpha() const {
50 return this->onReportsAlpha();
51 }
52
53 /**
54 * Cached value representing whether the frame has alpha,
55 * after compositing with the prior frame.
56 */
57 bool hasAlpha() const { return fHasAlpha; }
58
59 /**
60 * Cache whether the finished frame has alpha.
61 */
62 void setHasAlpha(bool alpha) { fHasAlpha = alpha; }
63
64 /**
65 * Whether enough of the frame has been read to determine
66 * fRequiredFrame and fHasAlpha.
67 */
68 bool reachedStartOfData() const { return fRequiredFrame != kUninitialized; }
69
70 /**
71 * The frame this one depends on.
72 *
73 * Must not be called until fRequiredFrame has been set properly.
74 */
75 int getRequiredFrame() const {
76 SkASSERT(this->reachedStartOfData());
77 return fRequiredFrame;
78 }
79
80 /**
81 * Set the frame that this frame depends on.
82 */
83 void setRequiredFrame(int req) { fRequiredFrame = req; }
84
85 /**
86 * Set the rectangle that is updated by this frame.
87 */
88 void setXYWH(int x, int y, int width, int height) {
89 fRect.setXYWH(x, y, width, height);
90 }
91
92 /**
93 * The rectangle that is updated by this frame.
94 */
95 SkIRect frameRect() const { return fRect; }
96
97 int xOffset() const { return fRect.x(); }
98 int yOffset() const { return fRect.y(); }
99 int width() const { return fRect.width(); }
100 int height() const { return fRect.height(); }
101
102 SkCodecAnimation::DisposalMethod getDisposalMethod() const {
103 return fDisposalMethod;
104 }
105
106 void setDisposalMethod(SkCodecAnimation::DisposalMethod disposalMethod) {
107 fDisposalMethod = disposalMethod;
108 }
109
110 /**
111 * Set the duration (in ms) to show this frame.
112 */
113 void setDuration(int duration) {
114 fDuration = duration;
115 }
116
117 /**
118 * Duration in ms to show this frame.
119 */
120 int getDuration() const {
121 return fDuration;
122 }
123
124 void setBlend(SkCodecAnimation::Blend blend) {
125 fBlend = blend;
126 }
127
128 SkCodecAnimation::Blend getBlend() const {
129 return fBlend;
130 }
131
132protected:
133 virtual bool onReportsAlpha() const = 0;
134
135private:
136 static constexpr int kUninitialized = -2;
137
138 const int fId;
139 bool fHasAlpha;
140 int fRequiredFrame;
141 SkIRect fRect;
142 SkCodecAnimation::DisposalMethod fDisposalMethod;
143 int fDuration;
144 SkCodecAnimation::Blend fBlend;
145};
146
147/**
148 * Base class for an object which holds the SkFrames of an
149 * image sequence.
150 */
151class SkFrameHolder : public SkNoncopyable {
152public:
153 SkFrameHolder()
154 : fScreenWidth(0)
155 , fScreenHeight(0)
156 {}
157
158 virtual ~SkFrameHolder() {}
159
160 /**
161 * Size of the image. Each frame will be contained in
162 * these dimensions (possibly after clipping).
163 */
164 int screenWidth() const { return fScreenWidth; }
165 int screenHeight() const { return fScreenHeight; }
166
167 /**
168 * Compute the opacity and required frame, based on
169 * whether the frame reportsAlpha and how it blends
170 * with prior frames.
171 */
172 void setAlphaAndRequiredFrame(SkFrame*);
173
174 /**
175 * Return the frame with frameId i.
176 */
177 const SkFrame* getFrame(int i) const {
178 return this->onGetFrame(i);
179 }
180
181protected:
182 int fScreenWidth;
183 int fScreenHeight;
184
185 virtual const SkFrame* onGetFrame(int i) const = 0;
186};
187
188#endif // SkFrameHolder_DEFINED