• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkGLCanvas()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 
~SkGLCanvas()37 SkGLCanvas::~SkGLCanvas() {
38     // call this now, while our override of restore() is in effect
39     this->restoreToCount(1);
40 }
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 
getViewport(SkIPoint * size) const44 bool SkGLCanvas::getViewport(SkIPoint* size) const {
45     if (size) {
46         *size = fViewportSize;
47     }
48     return true;
49 }
50 
setViewport(int width,int height)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 
createDevice(SkBitmap::Config,int width,int height,bool isOpaque,bool isForLayer)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 
LockTexCache(const SkBitmap & bitmap,GLuint * name,SkPoint * size)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 
UnlockTexCache(TexCache * cache)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 
GetTextureCacheMaxCount()118 size_t SkGLCanvas::GetTextureCacheMaxCount() {
119     SkAutoMutexAcquire amc(gTextureCacheMutex);
120     return gTextureCache.getMaxCount();
121 }
122 
GetTextureCacheMaxSize()123 size_t SkGLCanvas::GetTextureCacheMaxSize() {
124     SkAutoMutexAcquire amc(gTextureCacheMutex);
125     return gTextureCache.getMaxSize();
126 }
127 
SetTextureCacheMaxCount(size_t count)128 void SkGLCanvas::SetTextureCacheMaxCount(size_t count) {
129     SkAutoMutexAcquire amc(gTextureCacheMutex);
130     gTextureCache.setMaxCount(count);
131 }
132 
SetTextureCacheMaxSize(size_t size)133 void SkGLCanvas::SetTextureCacheMaxSize(size_t size) {
134     SkAutoMutexAcquire amc(gTextureCacheMutex);
135     gTextureCache.setMaxSize(size);
136 }
137 
138 ///////////////////////////////////////////////////////////////////////////////
139 
140 #include "SkGLTextCache.h"
141 
deleteCachesProc(SkGlyphCache * cache,void * texturesAreValid)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 
DeleteAllTextures()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 
AbandonAllTextures()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