| /* |
| * Copyright (C) 2011, 2012 Research In Motion Limited. All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #ifndef TextureCacheCompositingThread_h |
| #define TextureCacheCompositingThread_h |
| |
| #if USE(ACCELERATED_COMPOSITING) |
| |
| #include "Color.h" |
| #include "LayerTileIndex.h" |
| #include "Texture.h" |
| |
| #include <BlackBerryPlatformGraphics.h> |
| #include <wtf/HashMap.h> |
| #include <wtf/ListHashSet.h> |
| #include <wtf/Noncopyable.h> |
| #include <wtf/PassRefPtr.h> |
| #include <wtf/RefPtr.h> |
| #include <wtf/Vector.h> |
| |
| namespace WebCore { |
| |
| class IntRect; |
| |
| // A LRU cache for OpenGL textures. |
| class TextureCacheCompositingThread { |
| WTF_MAKE_NONCOPYABLE(TextureCacheCompositingThread); |
| WTF_MAKE_FAST_ALLOCATED; |
| public: |
| friend TextureCacheCompositingThread* textureCacheCompositingThread(); |
| |
| // Creates a new texture managed by this cache. |
| PassRefPtr<Texture> createTexture() |
| { |
| return Texture::create(); |
| } |
| |
| // Retrieve a texture from the cache. |
| PassRefPtr<Texture> textureForTiledContents(const Texture::HostType& contents, const IntRect& tileRect, const TileIndex&, bool isOpaque); |
| PassRefPtr<Texture> textureForColor(const Color&); |
| |
| // Update contents of an existing texture, or create a new one if texture is 0. |
| PassRefPtr<Texture> updateContents(const RefPtr<Texture>&, const Texture::HostType& contents, const IntRect& dirtyRect, const IntRect& tileRect, bool isOpaque); |
| |
| size_t memoryUsage() const { return m_memoryUsage; } |
| size_t memoryLimit() const { return m_memoryLimit; } |
| void setMemoryLimit(size_t limit) { m_memoryLimit = limit; } |
| |
| // Evict unprotected textures until we reach the limit provided. |
| void prune(size_t limit); |
| void prune() { prune(memoryLimit()); } |
| |
| // Evict all textures from the cache. |
| void clear(); |
| |
| // Update the LRU list. |
| void textureAccessed(Texture*); |
| |
| // Deleting destroyed textures is provided as a separate method, because |
| // there might not be an OpenGL context current when the texture destructor |
| // was called. Calling this makes sure to free any such textures. |
| void collectGarbage(); |
| |
| void textureDestroyed(Texture*); |
| void textureResized(Texture*, const IntSize& oldSize); |
| void textureSizeInBytesChanged(Texture*, int delta); |
| |
| // Undo the effects of eviction, if possible. |
| bool install(Texture*, const IntSize& textureSize = IntSize(0, 0), BlackBerry::Platform::Graphics::BufferType = BlackBerry::Platform::Graphics::BackedWhenNecessary); |
| bool resizeTexture(Texture*, const IntSize& newSize, BlackBerry::Platform::Graphics::BufferType = BlackBerry::Platform::Graphics::BackedWhenNecessary); |
| |
| private: |
| struct ZombieTexture { |
| explicit ZombieTexture(Texture* texture) |
| : id(texture->textureId()) |
| , size(texture->size()) |
| , sizeInBytes(texture->sizeInBytes()) |
| { |
| } |
| |
| Texture::GpuHandle id; |
| IntSize size; |
| size_t sizeInBytes; |
| }; |
| typedef ListHashSet<Texture* > TextureSet; |
| typedef HashMap<TileIndex, RefPtr<Texture> > TextureMap; |
| typedef Vector<ZombieTexture> Garbage; |
| |
| TextureCacheCompositingThread(); |
| ~TextureCacheCompositingThread(); |
| |
| Texture::GpuHandle allocateTextureId(const IntSize& textureSize, BlackBerry::Platform::Graphics::BufferType); |
| |
| void incMemoryUsage(int delta) { setMemoryUsage(memoryUsage() + delta); } |
| void decMemoryUsage(int delta) { setMemoryUsage(memoryUsage() - delta); } |
| void setMemoryUsage(size_t); |
| |
| void evict(const TextureSet::iterator&); |
| |
| // LRU set of weak pointers to textures. |
| TextureSet m_textures; |
| size_t m_memoryUsage; |
| size_t m_memoryLimit; |
| |
| struct ColorHash { |
| static unsigned hash(const Color& key) { return WTF::intHash(key.rgb()); } |
| static bool equal(const Color& a, const Color& b) { return a == b; } |
| static const bool safeToCompareToEmptyOrDeleted = true; |
| }; |
| struct ColorHashTraits : WTF::GenericHashTraits<Color> { |
| static const bool emptyValueIsZero = true; |
| // The deleted value is an invalid color with an RGB value of 0xFFFFFFFF. |
| // Such values do not naturally occur as colors. |
| // And empty value is an invalid color with an RGB value of 0x0. |
| static void constructDeletedValue(Color& slot) { new (&slot) Color(); *reinterpret_cast<RGBA32*>(&slot) = Color::white; } |
| static bool isDeletedValue(const Color& value) { return !value.isValid() && value.rgb() == Color::white; } |
| }; |
| typedef HashMap<Color, RefPtr<Texture>, ColorHash, ColorHashTraits> ColorTextureMap; |
| ColorTextureMap m_colors; |
| Garbage m_garbage; |
| }; |
| |
| TextureCacheCompositingThread* textureCacheCompositingThread(); |
| |
| } // namespace WebCore |
| |
| #endif // USE(ACCELERATED_COMPOSITING) |
| |
| #endif // TextureCacheCompositingThread_h |