blob: 50b23b9c6a5540e2bb1e537655bbdeb775ac66c1 [file] [log] [blame]
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include "base/containers/mru_cache.h"
#include "base/memory/memory_pressure_listener.h"
#include "gpu/command_buffer/common/discardable_handle.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/gpu_gles2_export.h"
namespace gpu {
namespace gles2 {
class TextureManager;
class TextureRef;
GPU_GLES2_EXPORT size_t DiscardableCacheSizeLimit();
GPU_GLES2_EXPORT size_t DiscardableCacheSizeLimitForPressure(
size_t base_cache_limit,
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
class GPU_GLES2_EXPORT ServiceDiscardableManager {
void InsertLockedTexture(uint32_t texture_id,
size_t texture_size,
gles2::TextureManager* texture_manager,
ServiceDiscardableHandle handle);
// Unlocks the indicated texture. If *|texture_to_unbind| is not nullptr,
// ServiceDiscardableManager has taken ownership of the given texture, and
// it is the callers responsibility to unbind it from any other objects.
// Returns false if the given texture_id has not been initialized for use
// with discardable.
bool UnlockTexture(uint32_t texture_id,
gles2::TextureManager* texture_manager,
gles2::TextureRef** texture_to_unbind);
// Locks the indicated texture, allowing it to be used in future GL commands.
// Returns false if the given texture_id has not been initialized for use
// with discardable.
bool LockTexture(uint32_t texture_id, gles2::TextureManager* texture_manager);
// Returns all unlocked texture refs to the texture_manager for deletion.
// After this point, this class will have no references to the given
// |texture_manager|.
void OnTextureManagerDestruction(gles2::TextureManager* texture_manager);
// Called when a texture is deleted, to clean up state.
void OnTextureDeleted(uint32_t texture_id,
gles2::TextureManager* texture_manager);
// Called by the TextureManager when a texture's size changes.
void OnTextureSizeChanged(uint32_t texture_id,
gles2::TextureManager* texture_manager,
size_t new_size);
// Test only functions:
size_t NumCacheEntriesForTesting() const { return entries_.size(); }
bool IsEntryLockedForTesting(uint32_t texture_id,
gles2::TextureManager* texture_manager) const;
size_t TotalSizeForTesting() const { return total_size_; }
gles2::TextureRef* UnlockedTextureRefForTesting(
uint32_t texture_id,
gles2::TextureManager* texture_manager) const;
void SetCacheSizeLimitForTesting(size_t cache_size_limit) {
cache_size_limit_ = cache_size_limit;
void HandleMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
void EnforceCacheSizeLimit(size_t limit);
struct GpuDiscardableEntry {
GpuDiscardableEntry(ServiceDiscardableHandle handle, size_t size);
GpuDiscardableEntry(const GpuDiscardableEntry& other);
GpuDiscardableEntry(GpuDiscardableEntry&& other);
ServiceDiscardableHandle handle;
scoped_refptr<gles2::TextureRef> unlocked_texture_ref;
// The current ref count of this object with regards to command buffer
// execution. May be out of sync with the handle's refcount, as the handle
// can be locked out of band with the command buffer.
uint32_t service_ref_count_ = 1;
size_t size;
struct GpuDiscardableEntryKey {
uint32_t texture_id;
gles2::TextureManager* texture_manager;
struct GpuDiscardableEntryKeyCompare {
bool operator()(const GpuDiscardableEntryKey& lhs,
const GpuDiscardableEntryKey& rhs) const {
return std::tie(lhs.texture_manager, lhs.texture_id) <
std::tie(rhs.texture_manager, rhs.texture_id);
using EntryCache = base::MRUCache<GpuDiscardableEntryKey,
EntryCache entries_;
// Total size of all |entries_|. The same as summing
// GpuDiscardableEntry::size for each entry.
size_t total_size_ = 0;
// The limit above which the cache will start evicting resources.
size_t cache_size_limit_ = 0;
} // namespace gpu