| 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 "builders/GrGLProgramBuilder.h" | 10 #include "builders/GrGLProgramBuilder.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 struct GrGpuGL::ProgramCache::Entry { | 25 struct GrGpuGL::ProgramCache::Entry { |
| 26 SK_DECLARE_INST_COUNT_ROOT(Entry); | 26 SK_DECLARE_INST_COUNT_ROOT(Entry); |
| 27 Entry() : fProgram(NULL), fLRUStamp(0) {} | 27 Entry() : fProgram(NULL), fLRUStamp(0) {} |
| 28 | 28 |
| 29 SkAutoTUnref<GrGLProgram> fProgram; | 29 SkAutoTUnref<GrGLProgram> fProgram; |
| 30 unsigned int fLRUStamp; | 30 unsigned int fLRUStamp; |
| 31 }; | 31 }; |
| 32 | 32 |
| 33 struct GrGpuGL::ProgramCache::ProgDescLess { | 33 struct GrGpuGL::ProgramCache::ProgDescLess { |
| 34 bool operator() (const GrGLProgramDesc& desc, const Entry* entry) { | 34 bool operator() (const GrProgramDesc& desc, const Entry* entry) { |
| 35 SkASSERT(entry->fProgram.get()); | 35 SkASSERT(entry->fProgram.get()); |
| 36 return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc()); | 36 return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc()); |
| 37 } | 37 } |
| 38 | 38 |
| 39 bool operator() (const Entry* entry, const GrGLProgramDesc& desc) { | 39 bool operator() (const Entry* entry, const GrProgramDesc& desc) { |
| 40 SkASSERT(entry->fProgram.get()); | 40 SkASSERT(entry->fProgram.get()); |
| 41 return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc); | 41 return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc); |
| 42 } | 42 } |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 GrGpuGL::ProgramCache::ProgramCache(GrGpuGL* gpu) | 45 GrGpuGL::ProgramCache::ProgramCache(GrGpuGL* gpu) |
| 46 : fCount(0) | 46 : fCount(0) |
| 47 , fCurrLRUStamp(0) | 47 , fCurrLRUStamp(0) |
| 48 , fGpu(gpu) | 48 , fGpu(gpu) |
| 49 #ifdef PROGRAM_CACHE_STATS | 49 #ifdef PROGRAM_CACHE_STATS |
| (...skipping 29 matching lines...) Expand all Loading... |
| 79 | 79 |
| 80 void GrGpuGL::ProgramCache::abandon() { | 80 void GrGpuGL::ProgramCache::abandon() { |
| 81 for (int i = 0; i < fCount; ++i) { | 81 for (int i = 0; i < fCount; ++i) { |
| 82 SkASSERT(fEntries[i]->fProgram.get()); | 82 SkASSERT(fEntries[i]->fProgram.get()); |
| 83 fEntries[i]->fProgram->abandon(); | 83 fEntries[i]->fProgram->abandon(); |
| 84 SkDELETE(fEntries[i]); | 84 SkDELETE(fEntries[i]); |
| 85 } | 85 } |
| 86 fCount = 0; | 86 fCount = 0; |
| 87 } | 87 } |
| 88 | 88 |
| 89 int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const { | 89 int GrGpuGL::ProgramCache::search(const GrProgramDesc& desc) const { |
| 90 ProgDescLess less; | 90 ProgDescLess less; |
| 91 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); | 91 return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less); |
| 92 } | 92 } |
| 93 | 93 |
| 94 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState, | 94 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState, D
rawType type) { |
| 95 const GrGLProgramDesc& desc, | |
| 96 DrawType type) { | |
| 97 #ifdef PROGRAM_CACHE_STATS | 95 #ifdef PROGRAM_CACHE_STATS |
| 98 ++fTotalRequests; | 96 ++fTotalRequests; |
| 99 #endif | 97 #endif |
| 100 | 98 |
| 101 Entry* entry = NULL; | 99 Entry* entry = NULL; |
| 102 | 100 |
| 103 uint32_t hashIdx = desc.getChecksum(); | 101 uint32_t hashIdx = optState.desc().getChecksum(); |
| 104 hashIdx ^= hashIdx >> 16; | 102 hashIdx ^= hashIdx >> 16; |
| 105 if (kHashBits <= 8) { | 103 if (kHashBits <= 8) { |
| 106 hashIdx ^= hashIdx >> 8; | 104 hashIdx ^= hashIdx >> 8; |
| 107 } | 105 } |
| 108 hashIdx &=((1 << kHashBits) - 1); | 106 hashIdx &=((1 << kHashBits) - 1); |
| 109 Entry* hashedEntry = fHashTable[hashIdx]; | 107 Entry* hashedEntry = fHashTable[hashIdx]; |
| 110 if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) { | 108 if (hashedEntry && hashedEntry->fProgram->getDesc() == optState.desc()) { |
| 111 SkASSERT(hashedEntry->fProgram); | 109 SkASSERT(hashedEntry->fProgram); |
| 112 entry = hashedEntry; | 110 entry = hashedEntry; |
| 113 } | 111 } |
| 114 | 112 |
| 115 int entryIdx; | 113 int entryIdx; |
| 116 if (NULL == entry) { | 114 if (NULL == entry) { |
| 117 entryIdx = this->search(desc); | 115 entryIdx = this->search(optState.desc()); |
| 118 if (entryIdx >= 0) { | 116 if (entryIdx >= 0) { |
| 119 entry = fEntries[entryIdx]; | 117 entry = fEntries[entryIdx]; |
| 120 #ifdef PROGRAM_CACHE_STATS | 118 #ifdef PROGRAM_CACHE_STATS |
| 121 ++fHashMisses; | 119 ++fHashMisses; |
| 122 #endif | 120 #endif |
| 123 } | 121 } |
| 124 } | 122 } |
| 125 | 123 |
| 126 if (NULL == entry) { | 124 if (NULL == entry) { |
| 127 // We have a cache miss | 125 // We have a cache miss |
| 128 #ifdef PROGRAM_CACHE_STATS | 126 #ifdef PROGRAM_CACHE_STATS |
| 129 ++fCacheMisses; | 127 ++fCacheMisses; |
| 130 #endif | 128 #endif |
| 131 GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc,
type, fGpu); | 129 GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, type,
fGpu); |
| 132 if (NULL == program) { | 130 if (NULL == program) { |
| 133 return NULL; | 131 return NULL; |
| 134 } | 132 } |
| 135 int purgeIdx = 0; | 133 int purgeIdx = 0; |
| 136 if (fCount < kMaxEntries) { | 134 if (fCount < kMaxEntries) { |
| 137 entry = SkNEW(Entry); | 135 entry = SkNEW(Entry); |
| 138 purgeIdx = fCount++; | 136 purgeIdx = fCount++; |
| 139 fEntries[purgeIdx] = entry; | 137 fEntries[purgeIdx] = entry; |
| 140 } else { | 138 } else { |
| 141 SkASSERT(fCount == kMaxEntries); | 139 SkASSERT(fCount == kMaxEntries); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 ++fCurrLRUStamp; | 196 ++fCurrLRUStamp; |
| 199 return entry->fProgram; | 197 return entry->fProgram; |
| 200 } | 198 } |
| 201 | 199 |
| 202 //////////////////////////////////////////////////////////////////////////////// | 200 //////////////////////////////////////////////////////////////////////////////// |
| 203 | 201 |
| 204 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) | 202 #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) |
| 205 | 203 |
| 206 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
opy) { | 204 bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
opy) { |
| 207 SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawSt
ate(), | 205 SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawSt
ate(), |
| 208 *this->caps(), | 206 this, |
| 207 dstCopy, |
| 209 type)); | 208 type)); |
| 210 | 209 |
| 211 if (!optState) { | 210 if (!optState) { |
| 212 return false; | 211 return false; |
| 213 } | 212 } |
| 214 | 213 |
| 215 // GrGpu::setupClipAndFlushState should have already checked this and bailed
if not true. | 214 // GrGpu::setupClipAndFlushState should have already checked this and bailed
if not true. |
| 216 SkASSERT(optState->getRenderTarget()); | 215 SkASSERT(optState->getRenderTarget()); |
| 217 | 216 |
| 218 if (kStencilPath_DrawType == type) { | 217 if (kStencilPath_DrawType == type) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 231 !optState->getStencil().doesWrite()) { | 230 !optState->getStencil().doesWrite()) { |
| 232 return false; | 231 return false; |
| 233 } | 232 } |
| 234 | 233 |
| 235 GrGLProgramDesc desc; | 234 GrGLProgramDesc desc; |
| 236 if (!GrGLProgramDesc::Build(*optState.get(), type, this, dstCopy, &desc)
) { | 235 if (!GrGLProgramDesc::Build(*optState.get(), type, this, dstCopy, &desc)
) { |
| 237 SkDEBUGFAIL("Failed to generate GL program descriptor"); | 236 SkDEBUGFAIL("Failed to generate GL program descriptor"); |
| 238 return false; | 237 return false; |
| 239 } | 238 } |
| 240 | 239 |
| 241 fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), desc, t
ype)); | 240 fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), type)); |
| 242 if (NULL == fCurrentProgram.get()) { | 241 if (NULL == fCurrentProgram.get()) { |
| 243 SkDEBUGFAIL("Failed to create program!"); | 242 SkDEBUGFAIL("Failed to create program!"); |
| 244 return false; | 243 return false; |
| 245 } | 244 } |
| 246 | 245 |
| 247 fCurrentProgram.get()->ref(); | 246 fCurrentProgram.get()->ref(); |
| 248 | 247 |
| 249 GrGLuint programID = fCurrentProgram->programID(); | 248 GrGLuint programID = fCurrentProgram->programID(); |
| 250 if (fHWProgramID != programID) { | 249 if (fHWProgramID != programID) { |
| 251 GL_CALL(UseProgram(programID)); | 250 GL_CALL(UseProgram(programID)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 270 } | 269 } |
| 271 // This must come after textures are flushed because a texture may need | 270 // This must come after textures are flushed because a texture may need |
| 272 // to be msaa-resolved (which will modify bound FBO state). | 271 // to be msaa-resolved (which will modify bound FBO state). |
| 273 this->flushRenderTarget(glRT, devRect); | 272 this->flushRenderTarget(glRT, devRect); |
| 274 | 273 |
| 275 return true; | 274 return true; |
| 276 } | 275 } |
| 277 | 276 |
| 278 void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { | 277 void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { |
| 279 SkAutoTUnref<GrOptDrawState> optState( | 278 SkAutoTUnref<GrOptDrawState> optState( |
| 280 GrOptDrawState::Create(this->getDrawState(), *this->caps(), | 279 GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(), |
| 281 PrimTypeToDrawType(info.primitiveType()))); | 280 PrimTypeToDrawType(info.primitiveType()))); |
| 282 | 281 |
| 283 // If the optState would is NULL it should have been caught in flushGraphics
State before getting | 282 // If the optState would is NULL it should have been caught in flushGraphics
State before getting |
| 284 // here. | 283 // here. |
| 285 SkASSERT(optState); | 284 SkASSERT(optState); |
| 286 | 285 |
| 287 GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride()); | 286 GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride()); |
| 288 | 287 |
| 289 size_t vertexOffsetInBytes = stride * info.startVertex(); | 288 size_t vertexOffsetInBytes = stride * info.startVertex(); |
| 290 | 289 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 GrGLAttribTypeToLayout(attribType).fCount, | 351 GrGLAttribTypeToLayout(attribType).fCount, |
| 353 GrGLAttribTypeToLayout(attribType).fType, | 352 GrGLAttribTypeToLayout(attribType).fType, |
| 354 GrGLAttribTypeToLayout(attribType).fNormalized, | 353 GrGLAttribTypeToLayout(attribType).fNormalized, |
| 355 stride, | 354 stride, |
| 356 reinterpret_cast<GrGLvoid*>( | 355 reinterpret_cast<GrGLvoid*>( |
| 357 vertexOffsetInBytes + vertexAttrib->fOffset)); | 356 vertexOffsetInBytes + vertexAttrib->fOffset)); |
| 358 } | 357 } |
| 359 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 358 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
| 360 } | 359 } |
| 361 } | 360 } |
| 361 |
| 362 void GrGpuGL::buildKey(const GrOptDrawState* optState, |
| 363 GrGpu::DrawType drawType, |
| 364 const GrDeviceCoordTexture* dstCopy, |
| 365 GrProgramDesc* desc) { |
| 366 SkASSERT(optState); |
| 367 if (!GrGLProgramDesc::Build(*optState, drawType, this, dstCopy, |
| 368 static_cast<GrGLProgramDesc*>(desc))) { |
| 369 SkDEBUGFAIL("Failed to generate GL program descriptor"); |
| 370 } |
| 371 } |
| OLD | NEW |