[GTK] [TextureMapper] Weird brightness with some videos with acceletared compositing
[WebKit.git] / Source / WebCore / platform / graphics / texmap / TextureMapper.cpp
1 /*
2  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  Library General Public License for more details.
13
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB.  If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "TextureMapper.h"
22
23 #include "FilterOperations.h"
24 #include "GraphicsLayer.h"
25 #include "TextureMapperImageBuffer.h"
26 #include "Timer.h"
27 #include <wtf/CurrentTime.h>
28
29 #if USE(TEXTURE_MAPPER)
30
31 namespace WebCore {
32
33 struct BitmapTexturePoolEntry {
34     explicit BitmapTexturePoolEntry(PassRefPtr<BitmapTexture> texture)
35         : m_texture(texture)
36     { }
37     inline void markUsed() { m_timeLastUsed = monotonicallyIncreasingTime(); }
38     static bool compareTimeLastUsed(const BitmapTexturePoolEntry& a, const BitmapTexturePoolEntry& b)
39     {
40         return a.m_timeLastUsed - b.m_timeLastUsed > 0;
41     }
42
43     RefPtr<BitmapTexture> m_texture;
44     double m_timeLastUsed;
45 };
46
47 class BitmapTexturePool {
48     WTF_MAKE_NONCOPYABLE(BitmapTexturePool);
49     WTF_MAKE_FAST_ALLOCATED;
50 public:
51     BitmapTexturePool();
52
53     PassRefPtr<BitmapTexture> acquireTexture(const IntSize&, TextureMapper*);
54
55 private:
56     void scheduleReleaseUnusedTextures();
57     void releaseUnusedTexturesTimerFired(Timer<BitmapTexturePool>*);
58
59     Vector<BitmapTexturePoolEntry> m_textures;
60     Timer<BitmapTexturePool> m_releaseUnusedTexturesTimer;
61
62     static const double s_releaseUnusedSecondsTolerance;
63     static const double s_releaseUnusedTexturesTimerInterval;
64 };
65
66 const double BitmapTexturePool::s_releaseUnusedSecondsTolerance = 3;
67 const double BitmapTexturePool::s_releaseUnusedTexturesTimerInterval = 0.5;
68
69 BitmapTexturePool::BitmapTexturePool()
70     : m_releaseUnusedTexturesTimer(this, &BitmapTexturePool::releaseUnusedTexturesTimerFired)
71 { }
72
73 void BitmapTexturePool::scheduleReleaseUnusedTextures()
74 {
75     if (m_releaseUnusedTexturesTimer.isActive())
76         m_releaseUnusedTexturesTimer.stop();
77
78     m_releaseUnusedTexturesTimer.startOneShot(s_releaseUnusedTexturesTimerInterval);
79 }
80
81 void BitmapTexturePool::releaseUnusedTexturesTimerFired(Timer<BitmapTexturePool>*)
82 {
83     if (m_textures.isEmpty())
84         return;
85
86     // Delete entries, which have been unused in s_releaseUnusedSecondsTolerance.
87     std::sort(m_textures.begin(), m_textures.end(), BitmapTexturePoolEntry::compareTimeLastUsed);
88
89     double minUsedTime = monotonicallyIncreasingTime() - s_releaseUnusedSecondsTolerance;
90     for (size_t i = 0; i < m_textures.size(); ++i) {
91         if (m_textures[i].m_timeLastUsed < minUsedTime) {
92             m_textures.remove(i, m_textures.size() - i);
93             break;
94         }
95     }
96 }
97
98 PassRefPtr<BitmapTexture> BitmapTexturePool::acquireTexture(const IntSize& size, TextureMapper* textureMapper)
99 {
100     BitmapTexturePoolEntry* selectedEntry = 0;
101     for (size_t i = 0; i < m_textures.size(); ++i) {
102         BitmapTexturePoolEntry* entry = &m_textures[i];
103
104         // If the surface has only one reference (the one in m_textures), we can safely reuse it.
105         if (entry->m_texture->refCount() > 1)
106             continue;
107
108         if (entry->m_texture->canReuseWith(size)) {
109             selectedEntry = entry;
110             break;
111         }
112     }
113
114     if (!selectedEntry) {
115         m_textures.append(BitmapTexturePoolEntry(textureMapper->createTexture()));
116         selectedEntry = &m_textures.last();
117     }
118
119     scheduleReleaseUnusedTextures();
120     selectedEntry->markUsed();
121     return selectedEntry->m_texture;
122 }
123
124 PassRefPtr<BitmapTexture> TextureMapper::acquireTextureFromPool(const IntSize& size, const BitmapTexture::Flags flags)
125 {
126     RefPtr<BitmapTexture> selectedTexture = m_texturePool->acquireTexture(size, this);
127     selectedTexture->reset(size, flags);
128     return selectedTexture;
129 }
130
131 PassOwnPtr<TextureMapper> TextureMapper::create(AccelerationMode mode)
132 {
133     if (mode == SoftwareMode)
134         return TextureMapperImageBuffer::create();
135     return platformCreateAccelerated();
136 }
137
138 TextureMapper::TextureMapper(AccelerationMode accelerationMode)
139     : m_context(0)
140     , m_interpolationQuality(InterpolationDefault)
141     , m_textDrawingMode(TextModeFill)
142     , m_texturePool(adoptPtr(new BitmapTexturePool()))
143     , m_accelerationMode(accelerationMode)
144     , m_isMaskMode(false)
145     , m_wrapMode(StretchWrap)
146 { }
147
148 TextureMapper::~TextureMapper()
149 { }
150
151 void BitmapTexture::updateContents(TextureMapper* textureMapper, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag updateContentsFlag)
152 {
153     std::unique_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(targetRect.size());
154     GraphicsContext* context = imageBuffer->context();
155     context->setImageInterpolationQuality(textureMapper->imageInterpolationQuality());
156     context->setTextDrawingMode(textureMapper->textDrawingMode());
157
158     IntRect sourceRect(targetRect);
159     sourceRect.setLocation(offset);
160     context->translate(-offset.x(), -offset.y());
161     sourceLayer->paintGraphicsLayerContents(*context, sourceRect);
162
163     RefPtr<Image> image = imageBuffer->copyImage(DontCopyBackingStore);
164
165     updateContents(image.get(), targetRect, IntPoint(), updateContentsFlag);
166 }
167
168 } // namespace
169
170 #endif