Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: Source/core/platform/graphics/DeferredImageDecoder.cpp

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "core/platform/graphics/DeferredImageDecoder.h"
28
29 #include "core/platform/graphics/ImageFrameGenerator.h"
30 #include "core/platform/graphics/LazyDecodingPixelRef.h"
31 #include "wtf/PassOwnPtr.h"
32
33 namespace WebCore {
34
35 namespace {
36
37 // URI label for a lazily decoded SkPixelRef.
38 const char labelLazyDecoded[] = "lazy";
39
40 } // namespace
41
42 bool DeferredImageDecoder::s_enabled = false;
43
44 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecode r)
45 : m_allDataReceived(false)
46 , m_actualDecoder(actualDecoder)
47 , m_orientation(DefaultImageOrientation)
48 , m_repetitionCount(cAnimationNone)
49 {
50 }
51
52 DeferredImageDecoder::~DeferredImageDecoder()
53 {
54 }
55
56 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileO ption gammaAndColorOption)
57 {
58 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, gammaAndColorOption);
59 return actualDecoder ? adoptPtr(new DeferredImageDecoder(actualDecoder.relea se())) : nullptr;
60 }
61
62 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::createForTesting(PassOwnP tr<ImageDecoder> decoder)
63 {
64 return adoptPtr(new DeferredImageDecoder(decoder));
65 }
66
67 bool DeferredImageDecoder::isLazyDecoded(const SkBitmap& bitmap)
68 {
69 return bitmap.pixelRef()
70 && bitmap.pixelRef()->getURI()
71 && !memcmp(bitmap.pixelRef()->getURI(), labelLazyDecoded, sizeof(labelLa zyDecoded));
72 }
73
74 void DeferredImageDecoder::setEnabled(bool enabled)
75 {
76 s_enabled = enabled;
77 }
78
79 String DeferredImageDecoder::filenameExtension() const
80 {
81 return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameEx tension;
82 }
83
84 ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index)
85 {
86 prepareLazyDecodedFrames();
87 if (index < m_lazyDecodedFrames.size()) {
88 // ImageFrameGenerator has the latest known alpha state. There will
89 // be a performance boost if this frame is opaque.
90 m_lazyDecodedFrames[index]->setHasAlpha(m_frameGenerator->hasAlpha(index ));
91 return m_lazyDecodedFrames[index].get();
92 }
93 if (m_actualDecoder)
94 return m_actualDecoder->frameBufferAtIndex(index);
95 return 0;
96 }
97
98 void DeferredImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
99 {
100 if (m_actualDecoder) {
101 m_data = data;
102 m_allDataReceived = allDataReceived;
103 m_actualDecoder->setData(data, allDataReceived);
104 prepareLazyDecodedFrames();
105 }
106
107 if (m_frameGenerator)
108 m_frameGenerator->setData(data, allDataReceived);
109 }
110
111 bool DeferredImageDecoder::isSizeAvailable()
112 {
113 // m_actualDecoder is 0 only if image decoding is deferred and that
114 // means image header decoded successfully and size is available.
115 return m_actualDecoder ? m_actualDecoder->isSizeAvailable() : true;
116 }
117
118 IntSize DeferredImageDecoder::size() const
119 {
120 return m_actualDecoder ? m_actualDecoder->size() : m_size;
121 }
122
123 IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const
124 {
125 // FIXME: Frame size is assumed to be uniform. This might not be true for
126 // future supported codecs.
127 return m_actualDecoder ? m_actualDecoder->frameSizeAtIndex(index) : m_size;
128 }
129
130 size_t DeferredImageDecoder::frameCount()
131 {
132 return m_actualDecoder ? m_actualDecoder->frameCount() : m_lazyDecodedFrames .size();
133 }
134
135 int DeferredImageDecoder::repetitionCount() const
136 {
137 return m_actualDecoder ? m_actualDecoder->repetitionCount() : m_repetitionCo unt;
138 }
139
140 size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
141 {
142 // If image decoding is deferred then frame buffer cache is managed by
143 // the compositor and this call is ignored.
144 return m_actualDecoder ? m_actualDecoder->clearCacheExceptFrame(clearExceptF rame) : 0;
145 }
146
147 bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const
148 {
149 if (m_actualDecoder)
150 return m_actualDecoder->frameHasAlphaAtIndex(index);
151 if (!m_frameGenerator->isMultiFrame())
152 return m_frameGenerator->hasAlpha(index);
153 return true;
154 }
155
156 bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const
157 {
158 if (m_actualDecoder)
159 return m_actualDecoder->frameIsCompleteAtIndex(index);
160 if (index < m_lazyDecodedFrames.size())
161 return m_lazyDecodedFrames[index]->status() == ImageFrame::FrameComplete ;
162 return false;
163 }
164
165 float DeferredImageDecoder::frameDurationAtIndex(size_t index) const
166 {
167 if (m_actualDecoder)
168 return m_actualDecoder->frameDurationAtIndex(index);
169 if (index < m_lazyDecodedFrames.size())
170 return m_lazyDecodedFrames[index]->duration();
171 return 0;
172 }
173
174 unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const
175 {
176 // If frame decoding is deferred then it is not managed by MemoryCache
177 // so return 0 here.
178 return m_frameGenerator ? 0 : m_actualDecoder->frameBytesAtIndex(index);
179 }
180
181 ImageOrientation DeferredImageDecoder::orientation() const
182 {
183 return m_actualDecoder ? m_actualDecoder->orientation() : m_orientation;
184 }
185
186 void DeferredImageDecoder::activateLazyDecoding()
187 {
188 if (m_frameGenerator)
189 return;
190 m_size = m_actualDecoder->size();
191 m_orientation = m_actualDecoder->orientation();
192 m_filenameExtension = m_actualDecoder->filenameExtension();
193 const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationN one || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
194 m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder ->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_all DataReceived, !isSingleFrame);
195 }
196
197 void DeferredImageDecoder::prepareLazyDecodedFrames()
198 {
199 if (!s_enabled
200 || !m_actualDecoder
201 || !m_actualDecoder->isSizeAvailable()
202 || m_actualDecoder->filenameExtension() == "ico")
203 return;
204
205 activateLazyDecoding();
206
207 const size_t previousSize = m_lazyDecodedFrames.size();
208 m_lazyDecodedFrames.resize(m_actualDecoder->frameCount());
209 for (size_t i = previousSize; i < m_lazyDecodedFrames.size(); ++i) {
210 OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame()));
211 frame->setSkBitmap(createLazyDecodingBitmap(i));
212 frame->setDuration(m_actualDecoder->frameDurationAtIndex(i));
213 frame->setStatus(m_actualDecoder->frameIsCompleteAtIndex(i) ? ImageFrame ::FrameComplete : ImageFrame::FramePartial);
214 m_lazyDecodedFrames[i] = frame.release();
215 }
216
217 // The last lazy decoded frame created from previous call might be
218 // incomplete so update its state.
219 if (previousSize)
220 m_lazyDecodedFrames[previousSize - 1]->setStatus(m_actualDecoder->frameI sCompleteAtIndex(previousSize - 1) ? ImageFrame::FrameComplete : ImageFrame::Fra mePartial);
221
222 if (m_allDataReceived) {
223 m_repetitionCount = m_actualDecoder->repetitionCount();
224 m_actualDecoder.clear();
225 m_data = nullptr;
226 }
227 }
228
229 SkBitmap DeferredImageDecoder::createLazyDecodingBitmap(size_t index)
230 {
231 IntSize decodedSize = m_actualDecoder->decodedSize();
232 ASSERT(decodedSize.width() > 0);
233 ASSERT(decodedSize.height() > 0);
234
235 // Creates a lazily decoded SkPixelRef that references the entire image with out scaling.
236 SkBitmap bitmap;
237 bitmap.setConfig(SkBitmap::kARGB_8888_Config, decodedSize.width(), decodedSi ze.height());
238 bitmap.setPixelRef(new LazyDecodingPixelRef(m_frameGenerator, index))->unref ();
239
240 // Use the URI to identify this as a lazily decoded SkPixelRef of type LazyD ecodingPixelRef.
241 // FIXME: It would be more useful to give the actual image URI.
242 bitmap.pixelRef()->setURI(labelLazyDecoded);
243
244 // Inform the bitmap that we will never change the pixels. This is a perform ance hint
245 // subsystems that may try to cache this bitmap (e.g. pictures, pipes, gpu, pdf, etc.)
246 bitmap.setImmutable();
247
248 return bitmap;
249 }
250
251 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const
252 {
253 // TODO: Implement.
254 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false;
255 }
256
257 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/DeferredImageDecoder.h ('k') | Source/core/platform/graphics/DeferredImageDecoderTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698