ImageDecoder can be deleted while the async decoder thread is still using it
[WebKit-https.git] / Source / WebCore / platform / graphics / ImageFrameCache.h
1 /*
2  * Copyright (C) 2016 Apple 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 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 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 #pragma once
27
28 #include "ImageFrame.h"
29 #include "TextStream.h"
30
31 #include <wtf/Forward.h>
32 #include <wtf/Optional.h>
33 #include <wtf/SynchronizedFixedQueue.h>
34 #include <wtf/WorkQueue.h>
35 #include <wtf/threads/BinarySemaphore.h>
36
37 namespace WebCore {
38
39 class GraphicsContext;
40 class Image;
41 class ImageDecoder;
42
43 class ImageFrameCache : public RefCounted<ImageFrameCache> {
44     friend class ImageSource;
45 public:
46     static Ref<ImageFrameCache> create(Image* image)
47     {
48         return adoptRef(*new ImageFrameCache(image));
49     }
50
51     static Ref<ImageFrameCache> create(NativeImagePtr&& nativeImage)
52     {
53         return adoptRef(*new ImageFrameCache(WTFMove(nativeImage)));
54     }
55
56     ~ImageFrameCache();
57
58     void setDecoder(ImageDecoder*);
59     ImageDecoder* decoder() const;
60
61     unsigned decodedSize() const { return m_decodedSize; }
62     void destroyAllDecodedData() { destroyDecodedData(frameCount(), frameCount()); }
63     void destroyAllDecodedDataExcludeFrame(size_t excludeFrame) { destroyDecodedData(frameCount(), excludeFrame); }
64     void destroyDecodedDataBeforeFrame(size_t beforeFrame) { destroyDecodedData(beforeFrame, beforeFrame); }
65     void destroyIncompleteDecodedData();
66
67     void growFrames();
68     void clearMetadata();
69     
70     // Asynchronous image decoding
71     void startAsyncDecodingQueue();
72     bool requestFrameAsyncDecodingAtIndex(size_t, SubsamplingLevel, const IntSize&);
73     void stopAsyncDecodingQueue();
74     bool hasAsyncDecodingQueue() const { return m_decodingQueue; }
75     bool isAsyncDecodingQueueIdle() const;
76
77     // Image metadata which is calculated either by the ImageDecoder or directly
78     // from the NativeImage if this class was created for a memory image.
79     bool isSizeAvailable();
80     size_t frameCount();
81     RepetitionCount repetitionCount();
82     String filenameExtension();
83     std::optional<IntPoint> hotSpot();
84     
85     // Image metadata which is calculated from the first ImageFrame.
86     IntSize size();
87     IntSize sizeRespectingOrientation();
88
89     Color singlePixelSolidColor();
90
91     // ImageFrame metadata which does not require caching the ImageFrame.
92     bool frameIsBeingDecodedAtIndex(size_t, const std::optional<IntSize>& sizeForDrawing);
93     bool frameIsCompleteAtIndex(size_t);
94     bool frameHasAlphaAtIndex(size_t);
95     bool frameHasImageAtIndex(size_t);
96     bool frameHasValidNativeImageAtIndex(size_t, const std::optional<SubsamplingLevel>&, const std::optional<IntSize>& sizeForDrawing);
97     bool frameHasDecodedNativeImage(size_t);
98     SubsamplingLevel frameSubsamplingLevelAtIndex(size_t);
99     
100     // ImageFrame metadata which forces caching or re-caching the ImageFrame.
101     IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
102     unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
103     float frameDurationAtIndex(size_t);
104     ImageOrientation frameOrientationAtIndex(size_t);
105     NativeImagePtr frameImageAtIndex(size_t, const std::optional<SubsamplingLevel>&, const std::optional<IntSize>& sizeForDrawing);
106
107 private:
108     ImageFrameCache(Image*);
109     ImageFrameCache(NativeImagePtr&&);
110
111     template<typename T, T (ImageDecoder::*functor)() const>
112     T metadata(const T& defaultValue, std::optional<T>* cachedValue = nullptr);
113
114     template<typename T, typename... Args>
115     T frameMetadataAtIndex(size_t, T (ImageFrame::*functor)(Args...) const, Args&&...);
116     
117     template<typename T, typename... Args>
118     T frameMetadataAtIndexCacheIfNeeded(size_t, T (ImageFrame::*functor)() const,  std::optional<T>* cachedValue, Args&&...);
119     
120     bool isDecoderAvailable() const { return m_decoder; }
121     void destroyDecodedData(size_t frameCount, size_t excludeFrame);
122     void decodedSizeChanged(long long decodedSize);
123     void didDecodeProperties(unsigned decodedPropertiesSize);
124     void decodedSizeIncreased(unsigned decodedSize);
125     void decodedSizeDecreased(unsigned decodedSize);
126     void decodedSizeReset(unsigned decodedSize);
127
128     void setNativeImage(NativeImagePtr&&);
129     void setFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing);
130     void setFrameMetadataAtIndex(size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing);
131     void replaceFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const std::optional<IntSize>& sizeForDrawing);
132     void cacheFrameNativeImageAtIndex(NativeImagePtr&&, size_t, SubsamplingLevel, const IntSize& sizeForDrawing);
133
134     Ref<WorkQueue> decodingQueue();
135
136     const ImageFrame& frameAtIndexCacheIfNeeded(size_t, ImageFrame::Caching, const std::optional<SubsamplingLevel>& = { }, const std::optional<IntSize>& sizeForDrawing = { });
137
138     Image* m_image { nullptr };
139     RefPtr<ImageDecoder> m_decoder;
140     unsigned m_decodedSize { 0 };
141     unsigned m_decodedPropertiesSize { 0 };
142
143     Vector<ImageFrame, 1> m_frames;
144
145     // Asynchronous image decoding.
146     struct ImageFrameRequest {
147         size_t index;
148         SubsamplingLevel subsamplingLevel;
149         IntSize sizeForDrawing;
150     };
151     static const int BufferSize = 8;
152     using FrameRequestQueue = SynchronizedFixedQueue<ImageFrameRequest, BufferSize>;
153     FrameRequestQueue m_frameRequestQueue;
154     RefPtr<WorkQueue> m_decodingQueue;
155
156     // Image metadata.
157     std::optional<bool> m_isSizeAvailable;
158     std::optional<size_t> m_frameCount;
159     std::optional<RepetitionCount> m_repetitionCount;
160     std::optional<String> m_filenameExtension;
161     std::optional<std::optional<IntPoint>> m_hotSpot;
162
163     // Image metadata which is calculated from the first ImageFrame.
164     std::optional<IntSize> m_size;
165     std::optional<IntSize> m_sizeRespectingOrientation;
166     std::optional<Color> m_singlePixelSolidColor;
167 };
168     
169 }