/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (C) 2009 Red Hat, Inc.
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.1 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, see .
*/
#ifndef _H_CANVAS
#define _H_CANVAS
#include "common.h"
#include "debug.h"
#include "region.h"
#include
#include "cache.hpp"
#include "shared_cache.hpp"
#include "canvas_base.h"
#include "canvas_utils.h"
#include "glz_decoded_image.h"
#include "glz_decoder.h"
enum CanvasType {
CANVAS_TYPE_INVALID,
CANVAS_TYPE_SW,
CANVAS_TYPE_GL,
CANVAS_TYPE_GDI,
};
template
class CHash : public Base {
public:
CHash()
{
memset(_hash, 0, sizeof(_hash));
}
~CHash()
{
}
void add(uint32_t id, T* data)
{
Item** item = &_hash[key(id)];
while (*item) {
PANIC_ON((*item)->id == id);
item = &(*item)->next;
}
*item = new Item(id, data);
}
bool is_present(uint32_t id)
{
Item* item = _hash[key(id)];
for (;;) {
if (!item) {
return false;
}
if (item->id != id) {
item = item->next;
continue;
}
return true;
}
}
T* get(uint32_t id)
{
Item* item = _hash[key(id)];
for (;;) {
PANIC_ON(!item);
if (item->id != id) {
item = item->next;
continue;
}
return item->data;
}
}
void remove(uint32_t id)
{
Item** item = &_hash[key(id)];
while (*item) {
if ((*item)->id == id) {
Item *rm_item = *item;
*item = rm_item->next;
delete rm_item;
return;
}
item = &(*item)->next;
}
THROW("id %lu, not found", id);
}
private:
inline uint32_t key(uint32_t id) {return id % HASH_SIZE;}
private:
class Item {
public:
Item(uint32_t in_id, T* data)
: id (in_id)
, next (NULL)
, data (data) {}
~Item()
{
}
uint64_t id;
Item* next;
T* data;
};
Item* _hash[HASH_SIZE];
};
class PixmapCacheTreat {
public:
static inline pixman_image_t *get(pixman_image_t *surf)
{
return pixman_image_ref(surf);
}
static inline void release(pixman_image_t *surf)
{
pixman_image_unref(surf);
}
static const char* name() { return "pixmap";}
};
class SpiceImageCacheBase;
typedef SharedCache PixmapCache;
class SpiceImageCacheBase {
public:
SpiceImageCache base;
static void op_put(SpiceImageCache *c, uint64_t id, pixman_image_t *surface)
{
PixmapCache* cache = reinterpret_cast(c);
cache->add(id, surface);
}
static pixman_image_t* op_get(SpiceImageCache *c, uint64_t id)
{
PixmapCache* cache = reinterpret_cast(c);
return cache->get(id);
}
SpiceImageCacheBase()
{
static SpiceImageCacheOps cache_ops = {
op_put,
op_get
};
base.ops = &cache_ops;
}
};
class SpiceImageSurfacesBase;
typedef CHash CSurfaces;
class SpiceImageSurfacesBase {
public:
SpiceImageSurfaces base;
static void op_put(SpiceImageSurfaces *c, uint32_t surface_id, SpiceCanvas *surface)
{
CSurfaces* cache = reinterpret_cast(c);
cache->add(surface_id, surface);
}
static SpiceCanvas* op_get(SpiceImageSurfaces *s, uint32_t surface_id)
{
CSurfaces* cache = reinterpret_cast(s);
return cache->get(surface_id);
}
static void op_del(SpiceImageSurfaces *c, uint32_t surface_id)
{
CSurfaces* cache = reinterpret_cast(c);
cache->remove(surface_id);
}
SpiceImageSurfacesBase()
{
static SpiceImageSurfacesOps cache_ops = {
op_get
};
base.ops = &cache_ops;
}
};
class Canvas;
typedef CHash