Home | History | Annotate | Download | only in gl
      1 #include "SkGLCanvas.h"
      2 #include "SkGLDevice.h"
      3 #include "SkBlitter.h"
      4 #include "SkDraw.h"
      5 #include "SkDrawProcs.h"
      6 #include "SkGL.h"
      7 #include "SkGlyphCache.h"
      8 #include "SkTemplates.h"
      9 #include "SkUtils.h"
     10 #include "SkXfermode.h"
     11 
     12 #ifdef SK_GL_DEVICE_FBO
     13     #define USE_FBO_DEVICE
     14     #include "SkGLDevice_FBO.h"
     15 #else
     16     #define USE_SWLAYER_DEVICE
     17     #include "SkGLDevice_SWLayer.h"
     18 #endif
     19 
     20 // maximum number of entries in our texture cache (before purging)
     21 #define kTexCountMax_Default    256
     22 // maximum number of bytes used (by gl) for the texture cache (before purging)
     23 #define kTexSizeMax_Default     (4 * 1024 * 1024)
     24 
     25 ///////////////////////////////////////////////////////////////////////////////
     26 
     27 SkGLCanvas::SkGLCanvas() {
     28     glEnable(GL_TEXTURE_2D);
     29     glEnable(GL_SCISSOR_TEST);
     30     glEnableClientState(GL_VERTEX_ARRAY);
     31 
     32     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     33 
     34     fViewportSize.set(0, 0);
     35 }
     36 
     37 SkGLCanvas::~SkGLCanvas() {
     38     // call this now, while our override of restore() is in effect
     39     this->restoreToCount(1);
     40 }
     41 
     42 ///////////////////////////////////////////////////////////////////////////////
     43 
     44 bool SkGLCanvas::getViewport(SkIPoint* size) const {
     45     if (size) {
     46         *size = fViewportSize;
     47     }
     48     return true;
     49 }
     50 
     51 bool SkGLCanvas::setViewport(int width, int height) {
     52     fViewportSize.set(width, height);
     53 
     54     const bool isOpaque = false; // should this be a parameter to setViewport?
     55     const bool isForLayer = false;   // viewport is the base layer
     56     SkDevice* device = this->createDevice(SkBitmap::kARGB_8888_Config, width,
     57                                           height, isOpaque, isForLayer);
     58     this->setDevice(device)->unref();
     59 
     60     return true;
     61 }
     62 
     63 SkDevice* SkGLCanvas::createDevice(SkBitmap::Config, int width, int height,
     64                                    bool isOpaque, bool isForLayer) {
     65     SkBitmap bitmap;
     66 
     67     bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
     68     bitmap.setIsOpaque(isOpaque);
     69 
     70 #ifdef USE_FBO_DEVICE
     71     return SkNEW_ARGS(SkGLDevice_FBO, (bitmap, isForLayer));
     72 #elif defined(USE_SWLAYER_DEVICE)
     73     if (isForLayer) {
     74         bitmap.allocPixels();
     75         if (!bitmap.isOpaque()) {
     76             bitmap.eraseColor(0);
     77         }
     78         return SkNEW_ARGS(SkGLDevice_SWLayer, (bitmap));
     79     } else {
     80         return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
     81     }
     82 #else
     83     return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
     84 #endif
     85 }
     86 
     87 ///////////////////////////////////////////////////////////////////////////////
     88 
     89 #include "SkTextureCache.h"
     90 #include "SkThread.h"
     91 
     92 static SkMutex gTextureCacheMutex;
     93 static SkTextureCache gTextureCache(kTexCountMax_Default, kTexSizeMax_Default);
     94 
     95 SkGLDevice::TexCache* SkGLDevice::LockTexCache(const SkBitmap& bitmap,
     96                                                  GLuint* name, SkPoint* size) {
     97     SkAutoMutexAcquire amc(gTextureCacheMutex);
     98 
     99     SkTextureCache::Entry* entry = gTextureCache.lock(bitmap);
    100     if (NULL != entry) {
    101         if (name) {
    102             *name = entry->name();
    103         }
    104         if (size) {
    105             *size = entry->texSize();
    106         }
    107     }
    108     return (TexCache*)entry;
    109 }
    110 
    111 void SkGLDevice::UnlockTexCache(TexCache* cache) {
    112     SkAutoMutexAcquire amc(gTextureCacheMutex);
    113     gTextureCache.unlock((SkTextureCache::Entry*)cache);
    114 }
    115 
    116 // public exposure of texture cache settings
    117 
    118 size_t SkGLCanvas::GetTextureCacheMaxCount() {
    119     SkAutoMutexAcquire amc(gTextureCacheMutex);
    120     return gTextureCache.getMaxCount();
    121 }
    122 
    123 size_t SkGLCanvas::GetTextureCacheMaxSize() {
    124     SkAutoMutexAcquire amc(gTextureCacheMutex);
    125     return gTextureCache.getMaxSize();
    126 }
    127 
    128 void SkGLCanvas::SetTextureCacheMaxCount(size_t count) {
    129     SkAutoMutexAcquire amc(gTextureCacheMutex);
    130     gTextureCache.setMaxCount(count);
    131 }
    132 
    133 void SkGLCanvas::SetTextureCacheMaxSize(size_t size) {
    134     SkAutoMutexAcquire amc(gTextureCacheMutex);
    135     gTextureCache.setMaxSize(size);
    136 }
    137 
    138 ///////////////////////////////////////////////////////////////////////////////
    139 
    140 #include "SkGLTextCache.h"
    141 
    142 static bool deleteCachesProc(SkGlyphCache* cache, void* texturesAreValid) {
    143     void* auxData;
    144     if (cache->getAuxProcData(SkGLDevice::GlyphCacheAuxProc, &auxData)) {
    145         bool valid = texturesAreValid != NULL;
    146         SkGLTextCache* textCache = static_cast<SkGLTextCache*>(auxData);
    147         // call this before delete, in case valid is false
    148         textCache->deleteAllStrikes(valid);
    149         // now free the memory for the cache itself
    150         SkDELETE(textCache);
    151         // now remove the entry in the glyphcache (does not call the proc)
    152         cache->removeAuxProc(SkGLDevice::GlyphCacheAuxProc);
    153     }
    154     return false;   // keep going
    155 }
    156 
    157 void SkGLCanvas::DeleteAllTextures() {
    158     // free the textures in our cache
    159 
    160     gTextureCacheMutex.acquire();
    161     gTextureCache.deleteAllCaches(true);
    162     gTextureCacheMutex.release();
    163 
    164     // now free the textures in the font cache
    165 
    166     SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(true));
    167 }
    168 
    169 void SkGLCanvas::AbandonAllTextures() {
    170     // abandon the textures in our cache
    171 
    172     gTextureCacheMutex.acquire();
    173     gTextureCache.deleteAllCaches(false);
    174     gTextureCacheMutex.release();
    175 
    176     // abandon the textures in the font cache
    177 
    178     SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(false));
    179 }
    180 
    181