Chromium Code Reviews| 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 | 8 |
| 9 | 9 |
| 10 #ifndef GrGpuGL_DEFINED | 10 #ifndef GrGpuGL_DEFINED |
| 11 #define GrGpuGL_DEFINED | 11 #define GrGpuGL_DEFINED |
| 12 | 12 |
| 13 | 13 |
| 14 #include "GrBinHashKey.h" | 14 #include "GrBinHashKey.h" |
| 15 #include "GrDrawState.h" | 15 #include "GrDrawState.h" |
| 16 #include "GrGpu.h" | 16 #include "GrGpu.h" |
| 17 #include "GrGLContext.h" | 17 #include "GrGLContext.h" |
| 18 #include "GrGLIndexBuffer.h" | 18 #include "GrGLIndexBuffer.h" |
| 19 #include "GrGLIRect.h" | 19 #include "GrGLIRect.h" |
| 20 #include "GrGLProgram.h" | 20 #include "GrGLProgram.h" |
| 21 #include "GrGLStencilBuffer.h" | 21 #include "GrGLStencilBuffer.h" |
| 22 #include "GrGLTexture.h" | 22 #include "GrGLTexture.h" |
| 23 #include "GrGLVertexArray.h" | |
| 23 #include "GrGLVertexBuffer.h" | 24 #include "GrGLVertexBuffer.h" |
| 24 #include "../GrTHashCache.h" | 25 #include "../GrTHashCache.h" |
| 25 | 26 |
| 26 class GrGpuGL : public GrGpu { | 27 class GrGpuGL : public GrGpu { |
| 27 public: | 28 public: |
| 28 GrGpuGL(const GrGLContext& ctx, GrContext* context); | 29 GrGpuGL(const GrGLContext& ctx, GrContext* context); |
| 29 virtual ~GrGpuGL(); | 30 virtual ~GrGpuGL(); |
| 30 | 31 |
| 31 const GrGLInterface* glInterface() const { return fGLContext.interface(); } | 32 const GrGLInterface* glInterface() const { return fGLContext.interface(); } |
| 32 GrGLBinding glBinding() const { return fGLContext.info().binding(); } | 33 GrGLBinding glBinding() const { return fGLContext.info().binding(); } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 47 int left, int top, | 48 int left, int top, |
| 48 int width, int height, | 49 int width, int height, |
| 49 GrPixelConfig config, | 50 GrPixelConfig config, |
| 50 size_t rowBytes) const SK_OVERRIDE; | 51 size_t rowBytes) const SK_OVERRIDE; |
| 51 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; | 52 virtual bool fullReadPixelsIsFasterThanPartial() const SK_OVERRIDE; |
| 52 | 53 |
| 53 virtual void abandonResources() SK_OVERRIDE; | 54 virtual void abandonResources() SK_OVERRIDE; |
| 54 | 55 |
| 55 const GrGLCaps& glCaps() const { return fGLContext.info().caps(); } | 56 const GrGLCaps& glCaps() const { return fGLContext.info().caps(); } |
| 56 | 57 |
| 57 // Callbacks to update state tracking when related GL objects are bound or d eleted | 58 // These functions should be used to bind GL objects. They track the GL stat e and skip redundant |
| 58 void notifyVertexBufferBind(GrGLuint id); | 59 // bindings. Making the equivalent glBind calls directly will confuse the st ate tracking. |
| 59 void notifyVertexBufferDelete(GrGLuint id); | 60 void bindVertexArray(GrGLuint id) { |
| 60 void notifyIndexBufferBind(GrGLuint id); | 61 fHWGeometryState.setVertexArrayID(this, id); |
| 61 void notifyIndexBufferDelete(GrGLuint id); | 62 } |
| 63 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) { | |
| 64 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id); | |
| 65 } | |
| 66 void bindVertexBuffer(GrGLuint id) { | |
| 67 fHWGeometryState.setVertexBufferID(this, id); | |
| 68 } | |
| 69 | |
| 70 // These callbacks update state tracking when GL objects are deleted. They a re called from | |
| 71 // GrGLResource onRelease functions. | |
| 72 void notifyVertexBufferDelete(GrGLuint id) { | |
| 73 fHWGeometryState.notifyVertexBufferDelete(id); | |
| 74 } | |
| 75 void notifyIndexBufferDelete(GrGLuint id) { | |
| 76 fHWGeometryState.notifyIndexBufferDelete(id); | |
| 77 } | |
| 78 void notifyVertexArrayDelete(GrGLuint id) { | |
|
jvanverth1
2013/03/07 16:17:44
Match the order of the notify*Delete methods with
bsalomon
2013/03/07 16:25:07
will do before landing.
| |
| 79 fHWGeometryState.notifyVertexArrayDelete(id); | |
| 80 } | |
| 62 void notifyTextureDelete(GrGLTexture* texture); | 81 void notifyTextureDelete(GrGLTexture* texture); |
| 63 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); | 82 void notifyRenderTargetDelete(GrRenderTarget* renderTarget); |
| 64 | 83 |
| 65 private: | 84 private: |
| 66 // GrGpu overrides | 85 // GrGpu overrides |
| 67 virtual void onResetContext() SK_OVERRIDE; | 86 virtual void onResetContext() SK_OVERRIDE; |
| 68 | 87 |
| 69 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, | 88 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, |
| 70 const void* srcData, | 89 const void* srcData, |
| 71 size_t rowBytes) SK_OVERRIDE; | 90 size_t rowBytes) SK_OVERRIDE; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 bool insideClip) SK_OVERRIDE; | 133 bool insideClip) SK_OVERRIDE; |
| 115 virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; | 134 virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; |
| 116 | 135 |
| 117 // binds texture unit in GL | 136 // binds texture unit in GL |
| 118 void setTextureUnit(int unitIdx); | 137 void setTextureUnit(int unitIdx); |
| 119 | 138 |
| 120 // Sets up vertex attribute pointers and strides. On return indexOffsetInByt es gives the offset | 139 // Sets up vertex attribute pointers and strides. On return indexOffsetInByt es gives the offset |
| 121 // an into the index buffer. It does not account for drawInfo.startIndex() b ut rather the start | 140 // an into the index buffer. It does not account for drawInfo.startIndex() b ut rather the start |
| 122 // index is relative to the returned offset. | 141 // index is relative to the returned offset. |
| 123 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes); | 142 void setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes); |
| 124 // binds appropriate vertex and index buffers. It also returns offsets for t he vertex and index | |
| 125 // buffers. These offsets account for placement within a pool buffer or CPU- side addresses for | |
| 126 // use with buffer 0. They do not account for start values in the DrawInfo ( which is not passed | |
| 127 // here). The vertex buffer that contains the vertex data is returned. It is not necessarily | |
| 128 // bound. | |
| 129 GrGLVertexBuffer* setBuffers(bool indexed, size_t* vertexOffsetInBytes, size _t* indexOffsetInBytes); | |
| 130 | 143 |
| 131 // Subclasses should call this to flush the blend state. | 144 // Subclasses should call this to flush the blend state. |
| 132 // The params should be the final coefficients to apply | 145 // The params should be the final coefficients to apply |
| 133 // (after any blending optimizations or dual source blending considerations | 146 // (after any blending optimizations or dual source blending considerations |
| 134 // have been accounted for). | 147 // have been accounted for). |
| 135 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); | 148 void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); |
| 136 | 149 |
| 137 bool hasExtension(const char* ext) const { return fGLContext.info().hasExten sion(ext); } | 150 bool hasExtension(const char* ext) const { return fGLContext.info().hasExten sion(ext); } |
| 138 | 151 |
| 139 const GrGLContext& glContext() const { return fGLContext; } | 152 const GrGLContext& glContext() const { return fGLContext; } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 } | 274 } |
| 262 } fHWScissorSettings; | 275 } fHWScissorSettings; |
| 263 | 276 |
| 264 GrGLIRect fHWViewport; | 277 GrGLIRect fHWViewport; |
| 265 | 278 |
| 266 /** | 279 /** |
| 267 * Tracks bound vertex and index buffers and vertex attrib array state. | 280 * Tracks bound vertex and index buffers and vertex attrib array state. |
| 268 */ | 281 */ |
| 269 class HWGeometryState { | 282 class HWGeometryState { |
| 270 public: | 283 public: |
| 271 HWGeometryState() { fAttribArrayCount = 0; this->invalidate();} | 284 HWGeometryState() { fVBOVertexArray = NULL; this->invalidate(); } |
| 285 | |
| 286 ~HWGeometryState() { SkSafeUnref(fVBOVertexArray); } | |
| 272 | 287 |
| 273 void setMaxAttribArrays(int max) { | 288 void invalidate() { |
| 274 fAttribArrayCount = max; | 289 fBoundVertexArrayIDIsValid = false; |
| 275 fAttribArrays.reset(max); | 290 fBoundVertexBufferIDIsValid = false; |
| 276 for (int i = 0; i < fAttribArrayCount; ++i) { | 291 fDefaultVertexArrayBoundIndexBufferID = false; |
| 277 fAttribArrays[i].invalidate(); | 292 fDefaultVertexArrayBoundIndexBufferIDIsValid = false; |
| 293 fDefaultVertexArrayAttribState.invalidate(); | |
| 294 } | |
| 295 | |
| 296 void notifyVertexArrayDelete(GrGLuint id) { | |
| 297 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { | |
| 298 // Does implicit bind to 0 | |
| 299 fBoundVertexArrayID = 0; | |
| 278 } | 300 } |
| 279 } | 301 } |
| 280 | 302 |
| 281 void invalidate() { | 303 void setVertexArrayID(GrGpuGL* gpu, GrGLuint arrayID) { |
| 282 fBoundVertexBufferIDIsValid = false; | 304 if (!gpu->glCaps().vertexArrayObjectSupport()) { |
| 283 fBoundIndexBufferIDIsValid = false; | 305 GrAssert(0 == arrayID); |
| 284 for (int i = 0; i < fAttribArrayCount; ++i) { | 306 return; |
| 285 fAttribArrays[i].invalidate(); | 307 } |
| 308 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { | |
| 309 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); | |
| 310 fBoundVertexArrayIDIsValid = true; | |
| 311 fBoundVertexArrayID = arrayID; | |
| 286 } | 312 } |
| 287 } | 313 } |
| 288 | 314 |
| 289 void notifyVertexBufferDelete(GrGLuint id) { | 315 void notifyVertexBufferDelete(GrGLuint id) { |
| 290 if (0 != id) { | 316 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) { |
| 291 if (this->isVertexBufferIDBound(id)) { | 317 fBoundVertexBufferID = 0; |
| 292 // deleting bound buffer does implied bind to 0 | 318 } |
| 293 this->setVertexBufferID(0); | 319 if (NULL != fVBOVertexArray) { |
| 294 } | 320 fVBOVertexArray->notifyVertexBufferDelete(id); |
| 295 for (int i = 0; i < fAttribArrayCount; ++i) { | 321 } |
| 296 if (fAttribArrays[i].isVertexBufferIDBound(id)) { | 322 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id); |
| 297 fAttribArrays[i].invalidate(); | 323 } |
| 298 } | 324 |
| 299 } | 325 void notifyIndexBufferDelete(GrGLuint id) { |
| 326 if (fDefaultVertexArrayBoundIndexBufferIDIsValid && | |
| 327 id == fDefaultVertexArrayBoundIndexBufferID) { | |
| 328 fDefaultVertexArrayBoundIndexBufferID = 0; | |
| 329 } | |
| 330 if (NULL != fVBOVertexArray) { | |
| 331 fVBOVertexArray->notifyIndexBufferDelete(id); | |
| 300 } | 332 } |
| 301 } | 333 } |
| 302 | 334 |
| 303 void notifyIndexBufferDelete(GrGLuint id) { | 335 void setVertexBufferID(GrGpuGL* gpu, GrGLuint id) { |
| 304 if (0 != id) { | 336 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) { |
| 305 if (this->isIndexBufferIDBound(id)) { | 337 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id )); |
| 306 // deleting bound buffer does implied bind to 0 | 338 fBoundVertexBufferIDIsValid = true; |
| 307 this->setIndexBufferID(0); | 339 fBoundVertexBufferID = id; |
| 308 } | |
| 309 } | 340 } |
| 310 } | 341 } |
| 311 | 342 |
| 312 void setVertexBufferID(GrGLuint id) { | 343 /** |
| 313 fBoundVertexBufferIDIsValid = true; | 344 * Binds the default vertex array and binds the index buffer. This is us ed when binding |
| 314 fBoundVertexBufferID = id; | 345 * an index buffer in order to update it. |
| 315 } | 346 */ |
| 316 | 347 void setIndexBufferIDOnDefaultVertexArray(GrGpuGL* gpu, GrGLuint id) { |
| 317 void setIndexBufferID(GrGLuint id) { | 348 this->setVertexArrayID(gpu, 0); |
| 318 fBoundIndexBufferIDIsValid = true; | 349 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid || |
| 319 fBoundIndexBufferID = id; | 350 id != fDefaultVertexArrayBoundIndexBufferID) { |
| 320 } | 351 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BU FFER, id)); |
| 321 | 352 fDefaultVertexArrayBoundIndexBufferIDIsValid = true; |
| 322 bool isVertexBufferIDBound(GrGLuint id) const { | 353 fDefaultVertexArrayBoundIndexBufferID = id; |
| 323 return fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID; | |
| 324 } | |
| 325 | |
| 326 bool isIndexBufferIDBound(GrGLuint id) const { | |
| 327 return fBoundIndexBufferIDIsValid && id == fBoundIndexBufferID; | |
| 328 } | |
| 329 | |
| 330 void setAttribArray(const GrGpuGL* gpu, | |
| 331 int index, | |
| 332 GrGLVertexBuffer* vertexBuffer, | |
| 333 GrGLint size, | |
| 334 GrGLenum type, | |
| 335 GrGLboolean normalized, | |
| 336 GrGLsizei stride, | |
| 337 GrGLvoid* offset) { | |
| 338 GrAssert(index >= 0 && index < fAttribArrayCount); | |
| 339 AttribArray* attrib = fAttribArrays.get() + index; | |
| 340 attrib->set(gpu, this, index, vertexBuffer, size, type, normalized, stride, offset); | |
| 341 } | |
| 342 | |
| 343 void disableUnusedAttribArrays(const GrGpuGL* gpu, | |
| 344 uint32_t usedAttribIndexMask) { | |
| 345 for (int i = 0; i < fAttribArrayCount; ++i) { | |
| 346 if (!(usedAttribIndexMask & (1 << i))) { | |
| 347 fAttribArrays[i].disable(gpu, i); | |
| 348 } | |
| 349 } | 354 } |
| 350 } | 355 } |
| 351 | 356 |
| 357 /** | |
| 358 * Binds the vertex array object that should be used to render from the vertex buffer. | |
| 359 * The vertex array is bound and its attrib array state object is return ed. The vertex | |
| 360 * buffer is bound. The index buffer (if non-NULL) is bound to the verte x array. The | |
| 361 * returned GrGLAttribArrayState should be used to set vertex attribute arrays. | |
| 362 */ | |
| 363 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGpuGL* gpu, | |
| 364 const GrGLVertexBuffer* vbuffer, | |
| 365 const GrGLIndexBuffer* i buffer); | |
| 366 | |
| 352 private: | 367 private: |
| 368 GrGLuint fBoundVertexArrayID; | |
| 353 GrGLuint fBoundVertexBufferID; | 369 GrGLuint fBoundVertexBufferID; |
| 354 GrGLuint fBoundIndexBufferID; | 370 bool fBoundVertexArrayIDIsValid; |
| 355 bool fBoundVertexBufferIDIsValid; | 371 bool fBoundVertexBufferIDIsValid; |
| 356 bool fBoundIndexBufferIDIsValid; | |
| 357 | 372 |
| 358 struct AttribArray { | 373 GrGLuint fDefaultVertexArrayBoundIndexBufferID; |
| 359 public: | 374 bool fDefaultVertexArrayBoundIndexBufferIDIsValid; |
| 360 void set(const GrGpuGL* gpu, | 375 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 |
| 361 HWGeometryState* geoState, | 376 // is bound. However, this class is internal to GrGpuGL and this object never leaks out of |
| 362 int index, | 377 // GrGpuGL. |
| 363 GrGLVertexBuffer* vertexBuffer, | 378 GrGLAttribArrayState fDefaultVertexArrayAttribState; |
| 364 GrGLint size, | |
| 365 GrGLenum type, | |
| 366 GrGLboolean normalized, | |
| 367 GrGLsizei stride, | |
| 368 GrGLvoid* offset); | |
| 369 | 379 |
| 370 void disable(const GrGpuGL* gpu, int index) { | 380 // This is used when we're using a core profile and the vertices are in a VBO. |
| 371 if (!fEnableIsValid || fEnabled) { | 381 GrGLVertexArray* fVBOVertexArray; |
| 372 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(inde x)); | |
| 373 fEnableIsValid = true; | |
| 374 fEnabled = false; | |
| 375 } | |
| 376 } | |
| 377 | |
| 378 void invalidate() { | |
| 379 fEnableIsValid = false; | |
| 380 fAttribPointerIsValid = false; | |
| 381 } | |
| 382 | |
| 383 bool isVertexBufferIDBound(GrGLuint id) const { | |
| 384 return fAttribPointerIsValid && id == fVertexBufferID; | |
| 385 } | |
| 386 private: | |
| 387 bool fEnableIsValid; | |
| 388 bool fAttribPointerIsValid; | |
| 389 bool fEnabled; | |
| 390 GrGLuint fVertexBufferID; | |
| 391 GrGLint fSize; | |
| 392 GrGLenum fType; | |
| 393 GrGLboolean fNormalized; | |
| 394 GrGLsizei fStride; | |
| 395 GrGLvoid* fOffset; | |
| 396 }; | |
| 397 SkAutoTArray<AttribArray> fAttribArrays; | |
| 398 int fAttribArrayCount; | |
| 399 } fHWGeometryState; | 382 } fHWGeometryState; |
| 400 | 383 |
| 401 struct { | 384 struct { |
| 402 GrBlendCoeff fSrcCoeff; | 385 GrBlendCoeff fSrcCoeff; |
| 403 GrBlendCoeff fDstCoeff; | 386 GrBlendCoeff fDstCoeff; |
| 404 GrColor fConstColor; | 387 GrColor fConstColor; |
| 405 bool fConstColorValid; | 388 bool fConstColorValid; |
| 406 TriState fEnabled; | 389 TriState fEnabled; |
| 407 | 390 |
| 408 void invalidate() { | 391 void invalidate() { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 438 // we record what stencil format worked last time to hopefully exit early | 421 // we record what stencil format worked last time to hopefully exit early |
| 439 // from our loop that tries stencil formats and calls check fb status. | 422 // from our loop that tries stencil formats and calls check fb status. |
| 440 int fLastSuccessfulStencilFmtIdx; | 423 int fLastSuccessfulStencilFmtIdx; |
| 441 | 424 |
| 442 bool fPrintedCaps; | 425 bool fPrintedCaps; |
| 443 | 426 |
| 444 typedef GrGpu INHERITED; | 427 typedef GrGpu INHERITED; |
| 445 }; | 428 }; |
| 446 | 429 |
| 447 #endif | 430 #endif |
| OLD | NEW |