| 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 |