#include "SkGLCanvas.h"
#include "SkGLDevice.h"
#include "SkBlitter.h"
#include "SkDraw.h"
#include "SkDrawProcs.h"
#include "SkGL.h"
#include "SkGlyphCache.h"
#include "SkTemplates.h"
#include "SkUtils.h"
#include "SkXfermode.h"

#ifdef SK_GL_DEVICE_FBO
    #define USE_FBO_DEVICE
    #include "SkGLDevice_FBO.h"
#else
    #define USE_SWLAYER_DEVICE
    #include "SkGLDevice_SWLayer.h"
#endif

// maximum number of entries in our texture cache (before purging)
#define kTexCountMax_Default    256
// maximum number of bytes used (by gl) for the texture cache (before purging)
#define kTexSizeMax_Default     (4 * 1024 * 1024)

///////////////////////////////////////////////////////////////////////////////

SkGLCanvas::SkGLCanvas() {
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_SCISSOR_TEST);
    glEnableClientState(GL_VERTEX_ARRAY);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    fViewportSize.set(0, 0);
}

SkGLCanvas::~SkGLCanvas() {
    // call this now, while our override of restore() is in effect
    this->restoreToCount(1);
}

///////////////////////////////////////////////////////////////////////////////

bool SkGLCanvas::getViewport(SkIPoint* size) const {
    if (size) {
        *size = fViewportSize;
    }
    return true;
}

bool SkGLCanvas::setViewport(int width, int height) {
    fViewportSize.set(width, height);

    const bool isOpaque = false; // should this be a parameter to setViewport?
    const bool isForLayer = false;   // viewport is the base layer
    SkDevice* device = this->createDevice(SkBitmap::kARGB_8888_Config, width,
                                          height, isOpaque, isForLayer);
    this->setDevice(device)->unref();

    return true;
}

SkDevice* SkGLCanvas::createDevice(SkBitmap::Config, int width, int height,
                                   bool isOpaque, bool isForLayer) {
    SkBitmap bitmap;
    
    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    bitmap.setIsOpaque(isOpaque);

#ifdef USE_FBO_DEVICE
    return SkNEW_ARGS(SkGLDevice_FBO, (bitmap, isForLayer));
#elif defined(USE_SWLAYER_DEVICE)
    if (isForLayer) {
        bitmap.allocPixels();
        if (!bitmap.isOpaque()) {
            bitmap.eraseColor(0);
        }
        return SkNEW_ARGS(SkGLDevice_SWLayer, (bitmap));
    } else {
        return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
    }
#else
    return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
#endif
}

///////////////////////////////////////////////////////////////////////////////

#include "SkTextureCache.h"
#include "SkThread.h"

static SkMutex gTextureCacheMutex;
static SkTextureCache gTextureCache(kTexCountMax_Default, kTexSizeMax_Default);

SkGLDevice::TexCache* SkGLDevice::LockTexCache(const SkBitmap& bitmap,
                                                 GLuint* name, SkPoint* size) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    
    SkTextureCache::Entry* entry = gTextureCache.lock(bitmap);
    if (NULL != entry) {
        if (name) {
            *name = entry->name();
        }
        if (size) {
            *size = entry->texSize();
        }
    }
    return (TexCache*)entry;
}

void SkGLDevice::UnlockTexCache(TexCache* cache) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.unlock((SkTextureCache::Entry*)cache);
}

// public exposure of texture cache settings

size_t SkGLCanvas::GetTextureCacheMaxCount() {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    return gTextureCache.getMaxCount();
}

size_t SkGLCanvas::GetTextureCacheMaxSize() {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    return gTextureCache.getMaxSize();
}

void SkGLCanvas::SetTextureCacheMaxCount(size_t count) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.setMaxCount(count);
}

void SkGLCanvas::SetTextureCacheMaxSize(size_t size) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.setMaxSize(size);
}

///////////////////////////////////////////////////////////////////////////////

#include "SkGLTextCache.h"

static bool deleteCachesProc(SkGlyphCache* cache, void* texturesAreValid) {
    void* auxData;
    if (cache->getAuxProcData(SkGLDevice::GlyphCacheAuxProc, &auxData)) {
        bool valid = texturesAreValid != NULL;
        SkGLTextCache* textCache = static_cast<SkGLTextCache*>(auxData);
        // call this before delete, in case valid is false
        textCache->deleteAllStrikes(valid);
        // now free the memory for the cache itself
        SkDELETE(textCache);
        // now remove the entry in the glyphcache (does not call the proc)
        cache->removeAuxProc(SkGLDevice::GlyphCacheAuxProc);
    }
    return false;   // keep going
}

void SkGLCanvas::DeleteAllTextures() {
    // free the textures in our cache

    gTextureCacheMutex.acquire();
    gTextureCache.deleteAllCaches(true);
    gTextureCacheMutex.release();
    
    // now free the textures in the font cache
    
    SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(true));
}

void SkGLCanvas::AbandonAllTextures() {
    // abandon the textures in our cache

    gTextureCacheMutex.acquire();
    gTextureCache.deleteAllCaches(false);
    gTextureCacheMutex.release();

    // abandon the textures in the font cache
    
    SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(false));
}

