| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 209 |
| 210 return ImageSize(frameSizeAtIndex(index)).area * | 210 return ImageSize(frameSizeAtIndex(index)).area * |
| 211 sizeof(ImageFrame::PixelData); | 211 sizeof(ImageFrame::PixelData); |
| 212 } | 212 } |
| 213 | 213 |
| 214 size_t ImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) { | 214 size_t ImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) { |
| 215 // Don't clear if there are no frames or only one frame. | 215 // Don't clear if there are no frames or only one frame. |
| 216 if (m_frameBufferCache.size() <= 1) | 216 if (m_frameBufferCache.size() <= 1) |
| 217 return 0; | 217 return 0; |
| 218 | 218 |
| 219 return clearCacheExceptTwoFrames(clearExceptFrame, kNotFound); | 219 // We expect that after this call, we'll be asked to decode frames after this |
| 220 // one. So we want to avoid clearing frames such that those requests would |
| 221 // force re-decoding from the beginning of the image. There are two cases in |
| 222 // which preserving |clearCacheExcept| frame is not enough to avoid that: |
| 223 // |
| 224 // 1. |clearExceptFrame| is not yet sufficiently decoded to decode subsequent |
| 225 // frames. We need the previous frame to sufficiently decode this frame. |
| 226 // 2. The disposal method of |clearExceptFrame| is DisposeOverwritePrevious. |
| 227 // In that case, we need to keep the required previous frame in the cache |
| 228 // to prevent re-decoding that frame when |clearExceptFrame| is disposed. |
| 229 // |
| 230 // If either 1 or 2 is true, store the required previous frame in |
| 231 // |clearExceptFrame2| so it won't be cleared. |
| 232 size_t clearExceptFrame2 = kNotFound; |
| 233 if (clearExceptFrame < m_frameBufferCache.size()) { |
| 234 const ImageFrame& frame = m_frameBufferCache[clearExceptFrame]; |
| 235 if (!frameStatusSufficientForSuccessors(clearExceptFrame) || |
| 236 frame.getDisposalMethod() == ImageFrame::DisposeOverwritePrevious) |
| 237 clearExceptFrame2 = frame.requiredPreviousFrameIndex(); |
| 238 } |
| 239 |
| 240 // Now |clearExceptFrame2| indicates the frame that |clearExceptFrame| |
| 241 // depends on, as described above. But if decoding is skipping forward past |
| 242 // intermediate frames, this frame may be insufficiently decoded. So we need |
| 243 // to keep traversing back through the required previous frames until we find |
| 244 // the nearest ancestor that is sufficiently decoded. Preserving that will |
| 245 // minimize the amount of future decoding needed. |
| 246 while (clearExceptFrame2 < m_frameBufferCache.size() && |
| 247 !frameStatusSufficientForSuccessors(clearExceptFrame2)) { |
| 248 clearExceptFrame2 = |
| 249 m_frameBufferCache[clearExceptFrame2].requiredPreviousFrameIndex(); |
| 250 } |
| 251 |
| 252 return clearCacheExceptTwoFrames(clearExceptFrame, clearExceptFrame2); |
| 220 } | 253 } |
| 221 | 254 |
| 222 size_t ImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1, | 255 size_t ImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1, |
| 223 size_t clearExceptFrame2) { | 256 size_t clearExceptFrame2) { |
| 224 size_t frameBytesCleared = 0; | 257 size_t frameBytesCleared = 0; |
| 225 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { | 258 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { |
| 226 if (m_frameBufferCache[i].getStatus() != ImageFrame::FrameEmpty && | 259 if (m_frameBufferCache[i].getStatus() != ImageFrame::FrameEmpty && |
| 227 i != clearExceptFrame1 && i != clearExceptFrame2) { | 260 i != clearExceptFrame1 && i != clearExceptFrame2) { |
| 228 frameBytesCleared += frameBytesAtIndex(i); | 261 frameBytesCleared += frameBytesAtIndex(i); |
| 229 clearFrameBuffer(i); | 262 clearFrameBuffer(i); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 m_targetColorSpace.get())) { | 540 m_targetColorSpace.get())) { |
| 508 return nullptr; | 541 return nullptr; |
| 509 } | 542 } |
| 510 | 543 |
| 511 m_sourceToTargetColorTransform = SkColorSpaceXform::New( | 544 m_sourceToTargetColorTransform = SkColorSpaceXform::New( |
| 512 m_embeddedColorSpace.get(), m_targetColorSpace.get()); | 545 m_embeddedColorSpace.get(), m_targetColorSpace.get()); |
| 513 return m_sourceToTargetColorTransform.get(); | 546 return m_sourceToTargetColorTransform.get(); |
| 514 } | 547 } |
| 515 | 548 |
| 516 } // namespace blink | 549 } // namespace blink |
| OLD | NEW |