1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrGpuGL_DEFINED 9 #define GrGpuGL_DEFINED 10 11 #include "GrBinHashKey.h" 12 #include "GrDrawState.h" 13 #include "GrGpu.h" 14 #include "GrGLContext.h" 15 #include "GrGLIndexBuffer.h" 16 #include "GrGLIRect.h" 17 #include "GrGLProgram.h" 18 #include "GrGLStencilBuffer.h" 19 #include "GrGLTexture.h" 20 #include "GrGLVertexArray.h" 21 #include "GrGLVertexBuffer.h" 22 #include "../GrTHashCache.h" 23 24 #ifdef SK_DEVELOPER 25 #define PROGRAM_CACHE_STATS 26 #endif 27 28 class GrGpuGL : public GrGpu { 29 public: 30 GrGpuGL(const GrGLContext& ctx, GrContext* context); 31 virtual ~GrGpuGL(); 32 33 const GrGLInterface* glInterface() const { return fGLContext.interface(); } 34 GrGLBinding glBinding() const { return fGLContext.info().binding(); } 35 GrGLVersion glVersion() const { return fGLContext.info().version(); } 36 GrGLSLGeneration glslGeneration() const { return fGLContext.info().glslGeneration(); } 37 38 // Used by GrGLProgram to bind necessary textures for GrGLEffects. 39 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture); 40 41 bool programUnitTest(int maxStages); 42 43 // GrGpu overrides 44 virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig, 45 GrPixelConfig surfaceConfig) const SK_OVERRIDE; 46 virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig, 47 GrPixelConfig surfaceConfig) const SK_OVERRIDE; 48 virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const SK_OVERRIDE; 49 virtual bool readPixelsWillPayForYFlip( 50 GrRenderTarget* renderTarget, 51 int left, int top, 52 int width, int height, 53 GrPixelConfig config, 54 size_t rowBytes) const SK_OVERRIDE; 55 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; 56 57 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE; 58 59 virtual void abandonResources() SK_OVERRIDE; 60 61 const GrGLCaps& glCaps() const { return *fGLContext.info().caps(); } 62 63 // These functions should be used to bind GL objects. They track the GL state and skip redundant 64 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. 65 void bindVertexArray(GrGLuint id) { 66 fHWGeometryState.setVertexArrayID(this, id); 67 } 68 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) { 69 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id); 70 } 71 void bindVertexBuffer(GrGLuint id) { 72 fHWGeometryState.setVertexBufferID(this, id); 73 } 74 75 // These callbacks update state tracking when GL objects are deleted. They are called from 76 // GrGLResource onRelease functions. 77 void notifyVertexArrayDelete(GrGLuint id) { 78 fHWGeometryState.notifyVertexArrayDelete(id); 79 } 80 void notifyVertexBufferDelete(GrGLuint id) { 81 fHWGeometryState.notifyVertexBufferDelete(id); 82 } 83 void notifyIndexBufferDelete(GrGLuint id) { 84 fHWGeometryState.notifyIndexBufferDelete(id); 85 } 86 void notifyTextureDelete(GrGLTexture* texture); 87 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); 88 89 protected: 90 virtual bool onCopySurface(GrSurface* dst, 91 GrSurface* src, 92 const SkIRect& srcRect, 93 const SkIPoint& dstPoint) SK_OVERRIDE; 94 95 virtual bool onCanCopySurface(GrSurface* dst, 96 GrSurface* src, 97 const SkIRect& srcRect, 98 const SkIPoint& dstPoint) SK_OVERRIDE; 99 100 private: 101 // GrGpu overrides 102 virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE; 103 104 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, 105 const void* srcData, 106 size_t rowBytes) SK_OVERRIDE; 107 virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, 108 bool dynamic) SK_OVERRIDE; 109 virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, 110 bool dynamic) SK_OVERRIDE; 111 virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE; 112 virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) SK_OVERRIDE; 113 virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) SK_OVERRIDE; 114 virtual bool createStencilBufferForRenderTarget(GrRenderTarget* rt, 115 int width, 116 int height) SK_OVERRIDE; 117 virtual bool attachStencilBufferToRenderTarget( 118 GrStencilBuffer* sb, 119 GrRenderTarget* rt) SK_OVERRIDE; 120 121 virtual void onClear(const SkIRect* rect, GrColor color) SK_OVERRIDE; 122 123 virtual void onForceRenderTargetFlush() SK_OVERRIDE; 124 125 virtual bool onReadPixels(GrRenderTarget* target, 126 int left, int top, 127 int width, int height, 128 GrPixelConfig, 129 void* buffer, 130 size_t rowBytes) SK_OVERRIDE; 131 132 virtual bool onWriteTexturePixels(GrTexture* texture, 133 int left, int top, int width, int height, 134 GrPixelConfig config, const void* buffer, 135 size_t rowBytes) SK_OVERRIDE; 136 137 virtual void onResolveRenderTarget(GrRenderTarget* target) SK_OVERRIDE; 138 139 virtual void onGpuDraw(const DrawInfo&) SK_OVERRIDE; 140 141 virtual void setStencilPathSettings(const GrPath&, 142 SkPath::FillType, 143 GrStencilSettings* settings) 144 SK_OVERRIDE; 145 virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; 146 147 virtual void clearStencil() SK_OVERRIDE; 148 virtual void clearStencilClip(const SkIRect& rect, 149 bool insideClip) SK_OVERRIDE; 150 virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; 151 152 // binds texture unit in GL 153 void setTextureUnit(int unitIdx); 154 155 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset 156 // an into the index buffer. It does not account for drawInfo.startIndex() but rather the start 157 // index is relative to the returned offset. 158 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes); 159 160 // Subclasses should call this to flush the blend state. 161 // The params should be the final coefficients to apply 162 // (after any blending optimizations or dual source blending considerations 163 // have been accounted for). 164 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); 165 166 bool hasExtension(const char* ext) const { return fGLContext.info().hasExtension(ext); } 167 168 const GrGLContext& glContext() const { return fGLContext; } 169 170 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 171 172 class ProgramCache : public ::GrNoncopyable { 173 public: 174 ProgramCache(const GrGLContext& gl); 175 ~ProgramCache(); 176 177 void abandon(); 178 GrGLProgram* getProgram(const GrGLProgramDesc& desc, 179 const GrEffectStage* colorStages[], 180 const GrEffectStage* coverageStages[]); 181 182 private: 183 enum { 184 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 185 // shader before evicting from the cache. 186 kMaxEntries = 32, 187 kHashBits = 6, 188 }; 189 190 struct Entry; 191 192 struct ProgDescLess; 193 194 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 195 // of the index of where it should be inserted. 196 int search(const GrGLProgramDesc& desc) const; 197 198 // sorted array of all the entries 199 Entry* fEntries[kMaxEntries]; 200 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary 201 // searching fEntries. 202 Entry* fHashTable[1 << kHashBits]; 203 204 int fCount; 205 unsigned int fCurrLRUStamp; 206 const GrGLContext& fGL; 207 #ifdef PROGRAM_CACHE_STATS 208 int fTotalRequests; 209 int fCacheMisses; 210 int fHashMisses; // cache hit but hash table missed 211 #endif 212 }; 213 214 // sets the matrix for path stenciling (uses the GL fixed pipe matrices) 215 void flushPathStencilMatrix(); 216 217 // flushes dithering, color-mask, and face culling stat 218 void flushMiscFixedFunctionState(); 219 220 // flushes the scissor. see the note on flushBoundTextureAndParams about 221 // flushing the scissor after that function is called. 222 void flushScissor(); 223 224 void initFSAASupport(); 225 226 // determines valid stencil formats 227 void initStencilFormats(); 228 229 // sets a texture unit to use for texture operations other than binding a texture to a program. 230 // ensures that such operations don't negatively interact with tracking bound textures. 231 void setScratchTextureUnit(); 232 233 // bound is region that may be modified and therefore has to be resolved. 234 // NULL means whole target. Can be an empty rect. 235 void flushRenderTarget(const SkIRect* bound); 236 void flushStencil(DrawType); 237 void flushAAState(DrawType); 238 239 bool configToGLFormats(GrPixelConfig config, 240 bool getSizedInternal, 241 GrGLenum* internalFormat, 242 GrGLenum* externalFormat, 243 GrGLenum* externalType); 244 // helper for onCreateTexture and writeTexturePixels 245 bool uploadTexData(const GrGLTexture::Desc& desc, 246 bool isNewTexture, 247 int left, int top, int width, int height, 248 GrPixelConfig dataConfig, 249 const void* data, 250 size_t rowBytes); 251 252 bool createRenderTargetObjects(int width, int height, 253 GrGLuint texID, 254 GrGLRenderTarget::Desc* desc); 255 256 void fillInConfigRenderableTable(); 257 258 GrGLContext fGLContext; 259 260 // GL program-related state 261 ProgramCache* fProgramCache; 262 SkAutoTUnref<GrGLProgram> fCurrentProgram; 263 264 /////////////////////////////////////////////////////////////////////////// 265 ///@name Caching of GL State 266 ///@{ 267 int fHWActiveTextureUnitIdx; 268 GrGLuint fHWProgramID; 269 270 GrGLProgram::SharedGLState fSharedGLProgramState; 271 272 enum TriState { 273 kNo_TriState, 274 kYes_TriState, 275 kUnknown_TriState 276 }; 277 278 // last scissor / viewport scissor state seen by the GL. 279 struct { 280 TriState fEnabled; 281 GrGLIRect fRect; 282 void invalidate() { 283 fEnabled = kUnknown_TriState; 284 fRect.invalidate(); 285 } 286 } fHWScissorSettings; 287 288 GrGLIRect fHWViewport; 289 290 /** 291 * Tracks bound vertex and index buffers and vertex attrib array state. 292 */ 293 class HWGeometryState { 294 public: 295 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); } 296 297 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); } 298 299 void invalidate() { 300 fBoundVertexArrayIDIsValid = false; 301 fBoundVertexBufferIDIsValid = false; 302 fDefaultVertexArrayBoundIndexBufferID = false; 303 fDefaultVertexArrayBoundIndexBufferIDIsValid = false; 304 fDefaultVertexArrayAttribState.invalidate(); 305 } 306 307 void notifyVertexArrayDelete(GrGLuint id) { 308 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 309 // Does implicit bind to 0 310 fBoundVertexArrayID = 0; 311 } 312 } 313 314 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) { 315 if (!gpu->glCaps().vertexArrayObjectSupport()) { 316 GrAssert(0 == arrayID); 317 return; 318 } 319 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 320 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 321 fBoundVertexArrayIDIsValid = true; 322 fBoundVertexArrayID = arrayID; 323 } 324 } 325 326 void notifyVertexBufferDelete(GrGLuint id) { 327 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) { 328 fBoundVertexBufferID = 0; 329 } 330 if (NULL != fVBOVertexArray) { 331 fVBOVertexArray->notifyVertexBufferDelete(id); 332 } 333 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id); 334 } 335 336 void notifyIndexBufferDelete(GrGLuint id) { 337 if (fDefaultVertexArrayBoundIndexBufferIDIsValid && 338 id == fDefaultVertexArrayBoundIndexBufferID) { 339 fDefaultVertexArrayBoundIndexBufferID = 0; 340 } 341 if (NULL != fVBOVertexArray) { 342 fVBOVertexArray->notifyIndexBufferDelete(id); 343 } 344 } 345 346 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) { 347 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) { 348 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id)); 349 fBoundVertexBufferIDIsValid = true; 350 fBoundVertexBufferID = id; 351 } 352 } 353 354 /** 355 * Binds the default vertex array and binds the index buffer. This is used when binding 356 * an index buffer in order to update it. 357 */ 358 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) { 359 this->setVertexArrayID(gpu, 0); 360 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid || 361 id != fDefaultVertexArrayBoundIndexBufferID) { 362 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id)); 363 fDefaultVertexArrayBoundIndexBufferIDIsValid = true; 364 fDefaultVertexArrayBoundIndexBufferID = id; 365 } 366 } 367 368 /** 369 * Binds the vertex array object that should be used to render from the vertex buffer. 370 * The vertex array is bound and its attrib array state object is returned. The vertex 371 * buffer is bound. The index buffer (if non-NULL) is bound to the vertex array. The 372 * returned GrGLAttribArrayState should be used to set vertex attribute arrays. 373 */ 374 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu, 375 const GrGLVertexBuffer* vbuffer, 376 const GrGLIndexBuffer* ibuffer); 377 378 private: 379 GrGLuint fBoundVertexArrayID; 380 GrGLuint fBoundVertexBufferID; 381 bool fBoundVertexArrayIDIsValid; 382 bool fBoundVertexBufferIDIsValid; 383 384 GrGLuint fDefaultVertexArrayBoundIndexBufferID; 385 bool fDefaultVertexArrayBoundIndexBufferIDIsValid; 386 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 387 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of 388 // GrGpuGL. 389 GrGLAttribArrayState fDefaultVertexArrayAttribState; 390 391 // This is used when we're using a core profile and the vertices are in a VBO. 392 GrGLVertexArray* fVBOVertexArray; 393 } fHWGeometryState; 394 395 struct { 396 GrBlendCoeff fSrcCoeff; 397 GrBlendCoeff fDstCoeff; 398 GrColor fConstColor; 399 bool fConstColorValid; 400 TriState fEnabled; 401 402 void invalidate() { 403 fSrcCoeff = kInvalid_GrBlendCoeff; 404 fDstCoeff = kInvalid_GrBlendCoeff; 405 fConstColorValid = false; 406 fEnabled = kUnknown_TriState; 407 } 408 } fHWBlendState; 409 410 struct { 411 TriState fMSAAEnabled; 412 TriState fSmoothLineEnabled; 413 void invalidate() { 414 fMSAAEnabled = kUnknown_TriState; 415 fSmoothLineEnabled = kUnknown_TriState; 416 } 417 } fHWAAState; 418 419 420 GrGLProgram::MatrixState fHWPathStencilMatrixState; 421 422 GrStencilSettings fHWStencilSettings; 423 TriState fHWStencilTestEnabled; 424 425 GrDrawState::DrawFace fHWDrawFace; 426 TriState fHWWriteToColor; 427 TriState fHWDitherEnabled; 428 GrRenderTarget* fHWBoundRenderTarget; 429 SkTArray<GrTexture*, true> fHWBoundTextures; 430 ///@} 431 432 // we record what stencil format worked last time to hopefully exit early 433 // from our loop that tries stencil formats and calls check fb status. 434 int fLastSuccessfulStencilFmtIdx; 435 436 typedef GrGpu INHERITED; 437 }; 438 439 #endif 440