This source file includes following definitions.
- m_taskObserverActive
- init
- get
- willProcessTask
- didProcessTask
- layerDidDraw
- layerTransientResourceAllocationChanged
- freeMemoryIfNecessary
- removeLayerFromList
- isInList
#include "config.h"
#include "platform/graphics/Canvas2DLayerManager.h"
#include "public/platform/Platform.h"
#include "wtf/StdLibExtras.h"
using blink::WebThread;
namespace {
enum {
DefaultMaxBytesAllocated = 64*1024*1024,
DefaultTargetBytesAllocated = 16*1024*1024,
};
}
namespace WebCore {
Canvas2DLayerManager::Canvas2DLayerManager()
: m_bytesAllocated(0)
, m_maxBytesAllocated(DefaultMaxBytesAllocated)
, m_targetBytesAllocated(DefaultTargetBytesAllocated)
, m_taskObserverActive(false)
{
}
Canvas2DLayerManager::~Canvas2DLayerManager()
{
ASSERT(!m_bytesAllocated);
ASSERT(!m_layerList.head());
ASSERT(!m_taskObserverActive);
}
void Canvas2DLayerManager::init(size_t maxBytesAllocated, size_t targetBytesAllocated)
{
ASSERT(maxBytesAllocated >= targetBytesAllocated);
m_maxBytesAllocated = maxBytesAllocated;
m_targetBytesAllocated = targetBytesAllocated;
if (m_taskObserverActive) {
blink::Platform::current()->currentThread()->removeTaskObserver(this);
m_taskObserverActive = false;
}
}
Canvas2DLayerManager& Canvas2DLayerManager::get()
{
DEFINE_STATIC_LOCAL(Canvas2DLayerManager, manager, ());
return manager;
}
void Canvas2DLayerManager::willProcessTask()
{
}
void Canvas2DLayerManager::didProcessTask()
{
ASSERT(m_taskObserverActive);
blink::Platform::current()->currentThread()->removeTaskObserver(this);
m_taskObserverActive = false;
Canvas2DLayerBridge* layer = m_layerList.head();
while (layer) {
Canvas2DLayerBridge* currentLayer = layer;
layer = layer->next();
currentLayer->limitPendingFrames();
}
}
void Canvas2DLayerManager::layerDidDraw(Canvas2DLayerBridge* layer)
{
if (isInList(layer)) {
if (layer != m_layerList.head()) {
m_layerList.remove(layer);
m_layerList.push(layer);
}
}
if (!m_taskObserverActive) {
m_taskObserverActive = true;
blink::Platform::current()->currentThread()->addTaskObserver(this);
}
}
void Canvas2DLayerManager::layerTransientResourceAllocationChanged(Canvas2DLayerBridge* layer, intptr_t deltaBytes)
{
ASSERT((intptr_t)m_bytesAllocated + deltaBytes >= 0);
m_bytesAllocated = (intptr_t)m_bytesAllocated + deltaBytes;
if (!isInList(layer) && layer->hasTransientResources()) {
m_layerList.push(layer);
} else if (isInList(layer) && !layer->hasTransientResources()) {
m_layerList.remove(layer);
layer->setNext(0);
layer->setPrev(0);
}
if (deltaBytes > 0)
freeMemoryIfNecessary();
}
void Canvas2DLayerManager::freeMemoryIfNecessary()
{
if (m_bytesAllocated >= m_maxBytesAllocated) {
Canvas2DLayerBridge* layer = m_layerList.tail();
while (layer && m_bytesAllocated > m_targetBytesAllocated) {
Canvas2DLayerBridge* currentLayer = layer;
layer = layer->prev();
currentLayer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesAllocated);
ASSERT(isInList(currentLayer) == currentLayer->hasTransientResources());
}
layer = m_layerList.tail();
while (m_bytesAllocated > m_targetBytesAllocated && layer) {
Canvas2DLayerBridge* currentLayer = layer;
layer = layer->prev();
currentLayer->flush();
currentLayer->freeMemoryIfPossible(m_bytesAllocated - m_targetBytesAllocated);
ASSERT(isInList(currentLayer) == currentLayer->hasTransientResources());
}
}
}
void Canvas2DLayerManager::removeLayerFromList(Canvas2DLayerBridge* layer)
{
ASSERT(isInList(layer));
ASSERT(!layer->hasTransientResources());
}
bool Canvas2DLayerManager::isInList(Canvas2DLayerBridge* layer) const
{
return layer->prev() || m_layerList.head() == layer;
}
}