1 |
anarchy 10/12/03 12:56:00 |
2 |
|
3 |
Added: fix-animated-gifs.patch |
4 |
Log: |
5 |
Resovle anitmated gif rendering when using cairo-1.10.0, bug #337813 |
6 |
|
7 |
(Portage version: 2.2.0_alpha6/cvs/Linux x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 net-libs/xulrunner/files/fix-animated-gifs.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/xulrunner/files/fix-animated-gifs.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-libs/xulrunner/files/fix-animated-gifs.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: fix-animated-gifs.patch |
16 |
=================================================================== |
17 |
# HG changeset patch |
18 |
# User Rafał Mużyło <galtgendo@××.pl> |
19 |
# Parent 69e253891ca3839b6d4b8f5cb7c0e6950bb66902 |
20 |
Fix animated gif flickering bug 597174 |
21 |
|
22 |
diff --git a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp |
23 |
--- a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp |
24 |
+++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp |
25 |
@@ -197,30 +197,29 @@ static NS_METHOD ReadDataOut(nsIInputStr |
26 |
} |
27 |
|
28 |
// Push any new rows according to mCurrentPass/mLastFlushedPass and |
29 |
// mCurrentRow/mLastFlushedRow. Note: caller is responsible for |
30 |
// updating mlastFlushed{Row,Pass}. |
31 |
nsresult |
32 |
nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows) |
33 |
{ |
34 |
- nsIntRect r(0, fromRow, mGIFStruct.width, rows); |
35 |
+ nsIntRect r(mGIFStruct.x_offset, mGIFStruct.y_offset + fromRow, mGIFStruct.width, rows); |
36 |
|
37 |
// Update image |
38 |
nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r); |
39 |
if (NS_FAILED(rv)) { |
40 |
return rv; |
41 |
} |
42 |
|
43 |
// Offset to the frame position |
44 |
// Only notify observer(s) for first frame |
45 |
if (!mGIFStruct.images_decoded && mObserver) { |
46 |
PRUint32 imgCurFrame; |
47 |
mImageContainer->GetCurrentFrameIndex(&imgCurFrame); |
48 |
- r.y += mGIFStruct.y_offset; |
49 |
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r); |
50 |
} |
51 |
return NS_OK; |
52 |
} |
53 |
|
54 |
nsresult |
55 |
nsGIFDecoder2::FlushImageData() |
56 |
{ |
57 |
diff --git a/modules/libpr0n/src/imgContainer.cpp b/modules/libpr0n/src/imgContainer.cpp |
58 |
--- a/modules/libpr0n/src/imgContainer.cpp |
59 |
+++ b/modules/libpr0n/src/imgContainer.cpp |
60 |
@@ -415,16 +415,18 @@ nsresult imgContainer::InternalAddFrameH |
61 |
|
62 |
nsAutoPtr<imgFrame> frame(aFrame); |
63 |
|
64 |
if (paletteData && paletteLength) |
65 |
frame->GetPaletteData(paletteData, paletteLength); |
66 |
|
67 |
frame->GetImageData(imageData, imageLength); |
68 |
|
69 |
+ frame->LockImageData(); |
70 |
+ |
71 |
mFrames.InsertElementAt(framenum, frame.forget()); |
72 |
mNumFrames++; |
73 |
|
74 |
return NS_OK; |
75 |
} |
76 |
|
77 |
nsresult imgContainer::InternalAddFrame(PRUint32 framenum, |
78 |
PRInt32 aX, PRInt32 aY, |
79 |
@@ -440,16 +442,21 @@ nsresult imgContainer::InternalAddFrame( |
80 |
return NS_ERROR_INVALID_ARG; |
81 |
|
82 |
nsAutoPtr<imgFrame> frame(new imgFrame()); |
83 |
NS_ENSURE_TRUE(frame, NS_ERROR_OUT_OF_MEMORY); |
84 |
|
85 |
nsresult rv = frame->Init(aX, aY, aWidth, aHeight, aFormat, aPaletteDepth); |
86 |
NS_ENSURE_SUCCESS(rv, rv); |
87 |
|
88 |
+ if (mFrames.Length() > 0) { |
89 |
+ imgFrame *prevframe = mFrames.ElementAt(mFrames.Length() - 1); |
90 |
+ prevframe->UnlockImageData(); |
91 |
+ } |
92 |
+ |
93 |
if (mFrames.Length() == 0) { |
94 |
return InternalAddFrameHelper(framenum, frame.forget(), imageData, imageLength, |
95 |
paletteData, paletteLength); |
96 |
} |
97 |
|
98 |
if (mFrames.Length() == 1) { |
99 |
// Since we're about to add our second frame, initialize animation stuff |
100 |
if (!ensureAnimExists()) |
101 |
diff --git a/modules/libpr0n/src/imgFrame.cpp b/modules/libpr0n/src/imgFrame.cpp |
102 |
--- a/modules/libpr0n/src/imgFrame.cpp |
103 |
+++ b/modules/libpr0n/src/imgFrame.cpp |
104 |
@@ -152,16 +152,17 @@ imgFrame::imgFrame() : |
105 |
mBlendMethod(1), /* imgIContainer::kBlendOver */ |
106 |
mSinglePixel(PR_FALSE), |
107 |
mNeverUseDeviceSurface(PR_FALSE), |
108 |
mFormatChanged(PR_FALSE), |
109 |
mCompositingFailed(PR_FALSE) |
110 |
#ifdef USE_WIN_SURFACE |
111 |
, mIsDDBSurface(PR_FALSE) |
112 |
#endif |
113 |
+ , mLocked(PR_FALSE) |
114 |
{ |
115 |
static PRBool hasCheckedOptimize = PR_FALSE; |
116 |
if (!hasCheckedOptimize) { |
117 |
if (PR_GetEnv("MOZ_DISABLE_IMAGE_OPTIMIZE")) { |
118 |
gDisableOptimize = PR_TRUE; |
119 |
} |
120 |
hasCheckedOptimize = PR_TRUE; |
121 |
} |
122 |
@@ -413,18 +414,17 @@ void imgFrame::Draw(gfxContext *aContext |
123 |
nsRefPtr<gfxASurface> surface; |
124 |
gfxImageSurface::gfxImageFormat format; |
125 |
|
126 |
NS_ASSERTION(!sourceRect.Intersect(subimage).IsEmpty(), |
127 |
"We must be allowed to sample *some* source pixels!"); |
128 |
|
129 |
PRBool doTile = !imageRect.Contains(sourceRect); |
130 |
if (doPadding || doPartialDecode) { |
131 |
- gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height) + |
132 |
- gfxPoint(aPadding.left, aPadding.top); |
133 |
+ gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height); |
134 |
|
135 |
if (!doTile && !mSinglePixel) { |
136 |
// Not tiling, and we have a surface, so we can account for |
137 |
// padding and/or a partial decode just by twiddling parameters. |
138 |
// First, update our user-space fill rect. |
139 |
sourceRect = sourceRect.Intersect(available); |
140 |
gfxMatrix imageSpaceToUserSpace = userSpaceToImageSpace; |
141 |
imageSpaceToUserSpace.Invert(); |
142 |
@@ -708,17 +708,17 @@ nsresult imgFrame::ImageUpdated(const ns |
143 |
mem->IsLowMemory(&lowMemory); |
144 |
if (lowMemory) |
145 |
return NS_ERROR_OUT_OF_MEMORY; |
146 |
|
147 |
mDecoded.UnionRect(mDecoded, aUpdateRect); |
148 |
|
149 |
// clamp to bounds, in case someone sends a bogus updateRect (I'm looking at |
150 |
// you, gif decoder) |
151 |
- nsIntRect boundsRect(0, 0, mSize.width, mSize.height); |
152 |
+ nsIntRect boundsRect(mOffset, mSize); |
153 |
mDecoded.IntersectRect(mDecoded, boundsRect); |
154 |
|
155 |
#ifdef XP_MACOSX |
156 |
if (mQuartzSurface) |
157 |
mQuartzSurface->Flush(); |
158 |
#endif |
159 |
return NS_OK; |
160 |
} |
161 |
@@ -806,17 +806,23 @@ void imgFrame::GetPaletteData(PRUint32 * |
162 |
*aPalette = (PRUint32 *) mPalettedImageData; |
163 |
*length = PaletteDataLength(); |
164 |
} |
165 |
} |
166 |
|
167 |
nsresult imgFrame::LockImageData() |
168 |
{ |
169 |
if (mPalettedImageData) |
170 |
- return NS_OK; |
171 |
+ return NS_ERROR_NOT_AVAILABLE; |
172 |
+ |
173 |
+ NS_ABORT_IF_FALSE(!mLocked, "Trying to lock already locked image data."); |
174 |
+ if (mLocked) { |
175 |
+ return NS_ERROR_FAILURE; |
176 |
+ } |
177 |
+ mLocked = PR_TRUE; |
178 |
|
179 |
if ((mOptSurface || mSinglePixel) && !mImageSurface) { |
180 |
// Recover the pixels |
181 |
mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height), |
182 |
gfxImageSurface::ImageFormatARGB32); |
183 |
if (!mImageSurface || mImageSurface->CairoStatus()) |
184 |
return NS_ERROR_OUT_OF_MEMORY; |
185 |
|
186 |
@@ -832,23 +838,35 @@ nsresult imgFrame::LockImageData() |
187 |
#ifdef USE_WIN_SURFACE |
188 |
mWinSurface = nsnull; |
189 |
#endif |
190 |
#ifdef XP_MACOSX |
191 |
mQuartzSurface = nsnull; |
192 |
#endif |
193 |
} |
194 |
|
195 |
+ if (mImageSurface) |
196 |
+ mImageSurface->Flush(); |
197 |
+ |
198 |
return NS_OK; |
199 |
} |
200 |
|
201 |
nsresult imgFrame::UnlockImageData() |
202 |
{ |
203 |
if (mPalettedImageData) |
204 |
- return NS_OK; |
205 |
+ return NS_ERROR_NOT_AVAILABLE; |
206 |
+ |
207 |
+ NS_ABORT_IF_FALSE(mLocked, "Unlocking an unlocked image!"); |
208 |
+ if (!mLocked) { |
209 |
+ return NS_ERROR_FAILURE; |
210 |
+ } |
211 |
+ mLocked = PR_FALSE; |
212 |
+ |
213 |
+ if (mImageSurface) |
214 |
+ mImageSurface->MarkDirty(); |
215 |
|
216 |
#ifdef XP_MACOSX |
217 |
if (mQuartzSurface) |
218 |
mQuartzSurface->Flush(); |
219 |
#endif |
220 |
return NS_OK; |
221 |
} |
222 |
|
223 |
@@ -895,17 +913,17 @@ PRInt32 imgFrame::GetBlendMethod() const |
224 |
|
225 |
void imgFrame::SetBlendMethod(PRInt32 aBlendMethod) |
226 |
{ |
227 |
mBlendMethod = (PRInt8)aBlendMethod; |
228 |
} |
229 |
|
230 |
PRBool imgFrame::ImageComplete() const |
231 |
{ |
232 |
- return mDecoded == nsIntRect(0, 0, mSize.width, mSize.height); |
233 |
+ return mDecoded == nsIntRect(mOffset, mSize); |
234 |
} |
235 |
|
236 |
// A hint from the image decoders that this image has no alpha, even |
237 |
// though we created is ARGB32. This changes our format to RGB24, |
238 |
// which in turn will cause us to Optimize() to RGB24. Has no effect |
239 |
// after Optimize() is called, though in all cases it will be just a |
240 |
// performance win -- the pixels are still correct and have the A byte |
241 |
// set to 0xff. |
242 |
diff --git a/modules/libpr0n/src/imgFrame.h b/modules/libpr0n/src/imgFrame.h |
243 |
--- a/modules/libpr0n/src/imgFrame.h |
244 |
+++ b/modules/libpr0n/src/imgFrame.h |
245 |
@@ -167,16 +167,17 @@ private: // data |
246 |
|
247 |
gfxASurface::gfxImageFormat mFormat; |
248 |
PRInt8 mPaletteDepth; |
249 |
PRInt8 mBlendMethod; |
250 |
PRPackedBool mSinglePixel; |
251 |
PRPackedBool mNeverUseDeviceSurface; |
252 |
PRPackedBool mFormatChanged; |
253 |
PRPackedBool mCompositingFailed; |
254 |
+ PRPackedBool mLocked; |
255 |
|
256 |
#ifdef XP_WIN |
257 |
PRPackedBool mIsDDBSurface; |
258 |
#endif |
259 |
|
260 |
}; |
261 |
|
262 |
#endif /* imgFrame_h */ |