OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrGpuGL.h" | 8 #include "GrGpuGL.h" |
9 | 9 |
10 #include "GrEffect.h" | 10 #include "GrEffect.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 struct GrGpuGL::ProgramCache::Entry { | 23 struct GrGpuGL::ProgramCache::Entry { |
24 SK_DECLARE_INST_COUNT_ROOT(Entry); | 24 SK_DECLARE_INST_COUNT_ROOT(Entry); |
25 Entry() : fProgram(NULL), fLRUStamp(0) {} | 25 Entry() : fProgram(NULL), fLRUStamp(0) {} |
26 | 26 |
27 SkAutoTUnref<GrGLProgram> fProgram; | 27 SkAutoTUnref<GrGLProgram> fProgram; |
28 unsigned int fLRUStamp; | 28 unsigned int fLRUStamp; |
29 }; | 29 }; |
30 | 30 |
31 struct GrGpuGL::ProgramCache::ProgDescLess { | 31 struct GrGpuGL::ProgramCache::ProgDescLess { |
32 bool operator() (const GrGLProgramDesc& desc, const Entry* entry) { | 32 bool operator() (const GrGLProgramDesc& desc, const Entry* entry) { |
33 SkASSERT(NULL != entry->fProgram.get()); | 33 SkASSERT(entry->fProgram.get()); |
34 return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc()); | 34 return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc()); |
35 } | 35 } |
36 | 36 |
37 bool operator() (const Entry* entry, const GrGLProgramDesc& desc) { | 37 bool operator() (const Entry* entry, const GrGLProgramDesc& desc) { |
38 SkASSERT(NULL != entry->fProgram.get()); | 38 SkASSERT(entry->fProgram.get()); |
39 return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc); | 39 return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc); |
40 } | 40 } |
41 }; | 41 }; |
42 | 42 |
43 GrGpuGL::ProgramCache::ProgramCache(GrGpuGL* gpu) | 43 GrGpuGL::ProgramCache::ProgramCache(GrGpuGL* gpu) |
44 : fCount(0) | 44 : fCount(0) |
45 , fCurrLRUStamp(0) | 45 , fCurrLRUStamp(0) |
46 , fGpu(gpu) | 46 , fGpu(gpu) |
47 #ifdef PROGRAM_CACHE_STATS | 47 #ifdef PROGRAM_CACHE_STATS |
48 , fTotalRequests(0) | 48 , fTotalRequests(0) |
(...skipping 21 matching lines...) Expand all Loading... |
70 0.f); | 70 0.f); |
71 int cacheHits = fTotalRequests - fCacheMisses; | 71 int cacheHits = fTotalRequests - fCacheMisses; |
72 SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / c
acheHits : 0.f); | 72 SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / c
acheHits : 0.f); |
73 SkDebugf("---------------------\n"); | 73 SkDebugf("---------------------\n"); |
74 } | 74 } |
75 #endif | 75 #endif |
76 } | 76 } |
77 | 77 |
78 void GrGpuGL::ProgramCache::abandon() { | 78 void GrGpuGL::ProgramCache::abandon() { |
79 for (int i = 0; i < fCount; ++i) { | 79 for (int i = 0; i < fCount; ++i) { |
80 SkASSERT(NULL != fEntries[i]->fProgram.get()); | 80 SkASSERT(fEntries[i]->fProgram.get()); |
81 fEntries[i]->fProgram->abandon(); | 81 fEntries[i]->fProgram->abandon(); |
82 SkDELETE(fEntries[i]); | 82 SkDELETE(fEntries[i]); |
83 } | 83 } |
84 fCount = 0; | 84 fCount = 0; |
85 } | 85 } |
86 | 86 |
87 int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const { | 87 int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const { |
88 ProgDescLess less; | 88 ProgDescLess less; |
89 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); | 89 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); |
90 } | 90 } |
91 | 91 |
92 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc, | 92 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc, |
93 const GrEffectStage* geometryProc
essor, | 93 const GrEffectStage* geometryProc
essor, |
94 const GrEffectStage* colorStages[
], | 94 const GrEffectStage* colorStages[
], |
95 const GrEffectStage* coverageStag
es[]) { | 95 const GrEffectStage* coverageStag
es[]) { |
96 #ifdef PROGRAM_CACHE_STATS | 96 #ifdef PROGRAM_CACHE_STATS |
97 ++fTotalRequests; | 97 ++fTotalRequests; |
98 #endif | 98 #endif |
99 | 99 |
100 Entry* entry = NULL; | 100 Entry* entry = NULL; |
101 | 101 |
102 uint32_t hashIdx = desc.getChecksum(); | 102 uint32_t hashIdx = desc.getChecksum(); |
103 hashIdx ^= hashIdx >> 16; | 103 hashIdx ^= hashIdx >> 16; |
104 if (kHashBits <= 8) { | 104 if (kHashBits <= 8) { |
105 hashIdx ^= hashIdx >> 8; | 105 hashIdx ^= hashIdx >> 8; |
106 } | 106 } |
107 hashIdx &=((1 << kHashBits) - 1); | 107 hashIdx &=((1 << kHashBits) - 1); |
108 Entry* hashedEntry = fHashTable[hashIdx]; | 108 Entry* hashedEntry = fHashTable[hashIdx]; |
109 if (NULL != hashedEntry && hashedEntry->fProgram->getDesc() == desc) { | 109 if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) { |
110 SkASSERT(NULL != hashedEntry->fProgram); | 110 SkASSERT(hashedEntry->fProgram); |
111 entry = hashedEntry; | 111 entry = hashedEntry; |
112 } | 112 } |
113 | 113 |
114 int entryIdx; | 114 int entryIdx; |
115 if (NULL == entry) { | 115 if (NULL == entry) { |
116 entryIdx = this->search(desc); | 116 entryIdx = this->search(desc); |
117 if (entryIdx >= 0) { | 117 if (entryIdx >= 0) { |
118 entry = fEntries[entryIdx]; | 118 entry = fEntries[entryIdx]; |
119 #ifdef PROGRAM_CACHE_STATS | 119 #ifdef PROGRAM_CACHE_STATS |
120 ++fHashMisses; | 120 ++fHashMisses; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 } else if (purgeIdx < entryIdx) { | 168 } else if (purgeIdx < entryIdx) { |
169 // If the entries array looks like this: | 169 // If the entries array looks like this: |
170 // aaaaPbbbbbEccccc | 170 // aaaaPbbbbbEccccc |
171 // we rearrange it to look like this: | 171 // we rearrange it to look like this: |
172 // aaaabbbbbPEccccc | 172 // aaaabbbbbPEccccc |
173 size_t copySize = (entryIdx - purgeIdx - 1) * sizeof(Entry*); | 173 size_t copySize = (entryIdx - purgeIdx - 1) * sizeof(Entry*); |
174 memmove(fEntries + purgeIdx, fEntries + purgeIdx + 1, copySize); | 174 memmove(fEntries + purgeIdx, fEntries + purgeIdx + 1, copySize); |
175 fEntries[entryIdx - 1] = entry; | 175 fEntries[entryIdx - 1] = entry; |
176 } | 176 } |
177 #ifdef SK_DEBUG | 177 #ifdef SK_DEBUG |
178 SkASSERT(NULL != fEntries[0]->fProgram.get()); | 178 SkASSERT(fEntries[0]->fProgram.get()); |
179 for (int i = 0; i < fCount - 1; ++i) { | 179 for (int i = 0; i < fCount - 1; ++i) { |
180 SkASSERT(NULL != fEntries[i + 1]->fProgram.get()); | 180 SkASSERT(fEntries[i + 1]->fProgram.get()); |
181 const GrGLProgramDesc& a = fEntries[i]->fProgram->getDesc(); | 181 const GrGLProgramDesc& a = fEntries[i]->fProgram->getDesc(); |
182 const GrGLProgramDesc& b = fEntries[i + 1]->fProgram->getDesc(); | 182 const GrGLProgramDesc& b = fEntries[i + 1]->fProgram->getDesc(); |
183 SkASSERT(GrGLProgramDesc::Less(a, b)); | 183 SkASSERT(GrGLProgramDesc::Less(a, b)); |
184 SkASSERT(!GrGLProgramDesc::Less(b, a)); | 184 SkASSERT(!GrGLProgramDesc::Less(b, a)); |
185 } | 185 } |
186 #endif | 186 #endif |
187 } | 187 } |
188 | 188 |
189 fHashTable[hashIdx] = entry; | 189 fHashTable[hashIdx] = entry; |
190 entry->fLRUStamp = fCurrLRUStamp; | 190 entry->fLRUStamp = fCurrLRUStamp; |
191 | 191 |
192 if (SK_MaxU32 == fCurrLRUStamp) { | 192 if (SK_MaxU32 == fCurrLRUStamp) { |
193 // wrap around! just trash our LRU, one time hit. | 193 // wrap around! just trash our LRU, one time hit. |
194 for (int i = 0; i < fCount; ++i) { | 194 for (int i = 0; i < fCount; ++i) { |
195 fEntries[i]->fLRUStamp = 0; | 195 fEntries[i]->fLRUStamp = 0; |
196 } | 196 } |
197 } | 197 } |
198 ++fCurrLRUStamp; | 198 ++fCurrLRUStamp; |
199 return entry->fProgram; | 199 return entry->fProgram; |
200 } | 200 } |
201 | 201 |
202 //////////////////////////////////////////////////////////////////////////////// | 202 //////////////////////////////////////////////////////////////////////////////// |
203 | 203 |
204 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 204 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
205 | 205 |
206 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
opy) { | 206 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
opy) { |
207 const GrDrawState& drawState = this->getDrawState(); | 207 const GrDrawState& drawState = this->getDrawState(); |
208 | 208 |
209 // GrGpu::setupClipAndFlushState should have already checked this and bailed
if not true. | 209 // GrGpu::setupClipAndFlushState should have already checked this and bailed
if not true. |
210 SkASSERT(NULL != drawState.getRenderTarget()); | 210 SkASSERT(drawState.getRenderTarget()); |
211 | 211 |
212 if (kStencilPath_DrawType == type) { | 212 if (kStencilPath_DrawType == type) { |
213 const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); | 213 const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); |
214 SkISize size; | 214 SkISize size; |
215 size.set(rt->width(), rt->height()); | 215 size.set(rt->width(), rt->height()); |
216 this->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(),
size, rt->origin()); | 216 this->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(),
size, rt->origin()); |
217 } else { | 217 } else { |
218 this->flushMiscFixedFunctionState(); | 218 this->flushMiscFixedFunctionState(); |
219 | 219 |
220 GrBlendCoeff srcCoeff; | 220 GrBlendCoeff srcCoeff; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 case kReserved_GeometrySrcType: | 307 case kReserved_GeometrySrcType: |
308 this->finalizeReservedVertices(); | 308 this->finalizeReservedVertices(); |
309 vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeom
Src().fVertexSize; | 309 vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeom
Src().fVertexSize; |
310 vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer; | 310 vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer; |
311 break; | 311 break; |
312 default: | 312 default: |
313 vbuf = NULL; // suppress warning | 313 vbuf = NULL; // suppress warning |
314 SkFAIL("Unknown geometry src type!"); | 314 SkFAIL("Unknown geometry src type!"); |
315 } | 315 } |
316 | 316 |
317 SkASSERT(NULL != vbuf); | 317 SkASSERT(vbuf); |
318 SkASSERT(!vbuf->isMapped()); | 318 SkASSERT(!vbuf->isMapped()); |
319 vertexOffsetInBytes += vbuf->baseOffset(); | 319 vertexOffsetInBytes += vbuf->baseOffset(); |
320 | 320 |
321 GrGLIndexBuffer* ibuf = NULL; | 321 GrGLIndexBuffer* ibuf = NULL; |
322 if (info.isIndexed()) { | 322 if (info.isIndexed()) { |
323 SkASSERT(NULL != indexOffsetInBytes); | 323 SkASSERT(indexOffsetInBytes); |
324 | 324 |
325 switch (this->getGeomSrc().fIndexSrc) { | 325 switch (this->getGeomSrc().fIndexSrc) { |
326 case kBuffer_GeometrySrcType: | 326 case kBuffer_GeometrySrcType: |
327 *indexOffsetInBytes = 0; | 327 *indexOffsetInBytes = 0; |
328 ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer; | 328 ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer; |
329 break; | 329 break; |
330 case kArray_GeometrySrcType: | 330 case kArray_GeometrySrcType: |
331 case kReserved_GeometrySrcType: | 331 case kReserved_GeometrySrcType: |
332 this->finalizeReservedIndices(); | 332 this->finalizeReservedIndices(); |
333 *indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLusho
rt); | 333 *indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLusho
rt); |
334 ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer; | 334 ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer; |
335 break; | 335 break; |
336 default: | 336 default: |
337 ibuf = NULL; // suppress warning | 337 ibuf = NULL; // suppress warning |
338 SkFAIL("Unknown geometry src type!"); | 338 SkFAIL("Unknown geometry src type!"); |
339 } | 339 } |
340 | 340 |
341 SkASSERT(NULL != ibuf); | 341 SkASSERT(ibuf); |
342 SkASSERT(!ibuf->isMapped()); | 342 SkASSERT(!ibuf->isMapped()); |
343 *indexOffsetInBytes += ibuf->baseOffset(); | 343 *indexOffsetInBytes += ibuf->baseOffset(); |
344 } | 344 } |
345 GrGLAttribArrayState* attribState = | 345 GrGLAttribArrayState* attribState = |
346 fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); | 346 fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); |
347 | 347 |
348 if (fCurrentProgram->hasVertexShader()) { | 348 if (fCurrentProgram->hasVertexShader()) { |
349 int vertexAttribCount = this->getDrawState().getVertexAttribCount(); | 349 int vertexAttribCount = this->getDrawState().getVertexAttribCount(); |
350 uint32_t usedAttribArraysMask = 0; | 350 uint32_t usedAttribArraysMask = 0; |
351 const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttri
bs(); | 351 const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttri
bs(); |
(...skipping 13 matching lines...) Expand all Loading... |
365 GrGLAttribTypeToLayout(attribType).fType, | 365 GrGLAttribTypeToLayout(attribType).fType, |
366 GrGLAttribTypeToLayout(attribType).fNormalized, | 366 GrGLAttribTypeToLayout(attribType).fNormalized, |
367 stride, | 367 stride, |
368 reinterpret_cast<GrGLvoid*>( | 368 reinterpret_cast<GrGLvoid*>( |
369 vertexOffsetInBytes + vertexAttrib->fOffset)); | 369 vertexOffsetInBytes + vertexAttrib->fOffset)); |
370 } | 370 } |
371 } | 371 } |
372 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 372 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
373 } | 373 } |
374 } | 374 } |
OLD | NEW |